当前位置: 首页 > 知识库问答 >
问题:

如何保存包含实体的新学员,但不创建这些实体,因为它们已经存在于数据库中?

苏彭薄
2023-03-14

我想保存一个学生,一个学生有一个TargetAudience对象作为属性。这些目标受众都已经在我的数据库中硬编码好了。(targetaudience=校园专业)。现在当我这样发帖时:

{
    "user": {
        "userName": "jan",
        "password": "tibo123",
        "role": "ROLE_STUDENT"
    },
    "targetAudience": {
        "majorCode": "IW E-ICT",
        "campus": {
            "name": "GroepT",
            "street": "Andreas Vesaliusstraat",
            "postalCode": "3000",
            "streetNr": "13"
        }
    }
}

它不起作用,因为每次它为校园创建一个新对象,并且因为我使用名称作为主键,它都会抛出一个异常。spring data jpa不应该查看实体allready是否存在,然后使用它吗?或者我该怎么做?

抱歉我没说清楚这是我第一次发帖

大学生爪哇:


package com.bachproject.demo.student;

import com.bachproject.demo.onderwerp.Onderwerp;
import com.bachproject.demo.targetAudience.TargetAudience;
import com.bachproject.demo.user.User;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;
import java.util.List;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Student {

    @Id
    @SequenceGenerator(
            name = "student_sequence",
            sequenceName = "student_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "student_sequence"
    )
    private Long studentId;

    @OneToOne(
            cascade = CascadeType.ALL,
            fetch = FetchType.EAGER,
            optional = true
    )
    @JoinColumn(
            name = "user_id",
            referencedColumnName = "userId"
    )
    private User user;

    @OneToOne(
            cascade = CascadeType.ALL,
            fetch = FetchType.EAGER,
            optional = true
    )
    @JoinColumn(
            name = "target_audience",
            referencedColumnName = "TargetAudienceId"
    )
    private TargetAudience targetAudience;

    //private List<Onderwerp> preferences;

}

学生管理员。JAVA

package com.bachproject.demo.student;

import com.bachproject.demo.onderwerp.Onderwerp;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;

import java.util.List;

@RestController
@RequestMapping("/students")
public class StudentController {

    @Autowired
    private StudentService studentService;

    @GetMapping
    @CrossOrigin(origins = "*")
    public List<Student> getStudents(){
        return studentService.getStudents();
    }

    @PostMapping("/register")
    @CrossOrigin(origins = "*")
    public Student registerStudent(@RequestBody Student student) {
        System.out.println(student);
        return studentService.registerStudent(student);
    }
}

学生ervice.java:

package com.bachproject.demo.student;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class StudentService {

    @Autowired
    private StudentRepository studentRepository;

    public List<Student> getStudents() {
        return studentRepository.findAll();
    }

    public Student registerStudent(Student student) {
        return studentRepository.save(student);
    }
}

目标观众。爪哇:

package com.bachproject.demo.targetAudience;

import com.bachproject.demo.campus.Campus;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.*;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class TargetAudience {

    @Id
    @SequenceGenerator(
            name = "targetAudience_sequence",
            sequenceName = "targetAudience_sequence",
            allocationSize = 1
    )
    @GeneratedValue(
            strategy = GenerationType.SEQUENCE,
            generator = "targetAudience_sequence"
    )
    private Long TargetAudienceId;

    // for example IW E-ICT-> industriele wetenschappen Elektronica ICT
    private String majorCode;

    @OneToOne(
            cascade = CascadeType.ALL,
            fetch = FetchType.EAGER,
            optional = true
    )
    @JoinColumn(
            name = "campus",
            referencedColumnName = "name"
    )
    private Campus campus;

}

Campus.java:

package com.bachproject.demo.campus;

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.persistence.Entity;
import javax.persistence.Id;

@Entity
@Data
@AllArgsConstructor
@NoArgsConstructor
public class Campus {

    @Id
    private String name;

    private String street;
    private String postalCode;
    private String streetNr;
}

共有1个答案

尹乐邦
2023-03-14

您在试图保存时遇到了什么异常?堆栈跟踪会更有帮助。然而,你可以通过两种方式来解决这个问题

或者,如果您想完全避免保存TargetAudience,您可以在@瞬态注释中注释TargetAudience属性,这样,它就不会被考虑用于数据库保存。

或者,JPA每次都试图用新的主键保存该对象,因为该对象处于分离状态(如果您的JPA提供程序是hibernate,这是默认的JPA提供程序)。您应该修改StudentService中的registerStudent()方法,如-

public Student registerStudent(Student student) {
    TargetAudience targetAudience = targetAudienceRepository.findByMajorCode(student.getTargetAudience().getMajorCode());
    student.setTargetAudience(targetAudience);
    return student;
}

因此,您从数据库中显式地获取TargetAudience,并将其设置为您要获取的学生对象。这样,获取的目标受众将处于持久状态(而不是分离状态),并且它不会再次尝试分配新的主键。

 类似资料:
  • 我正在与用户一起制作一个应用程序。用户有一个id,该id使用以下Hibernate注释自动分配: 这一切都很好,但问题是,每次我运行应用程序(同时添加同一个用户)时,它都会为用户分配一个新id,而不管该用户是否已经存在。 我该怎么做才能使现有用户在每次运行应用程序时都不会获得新id,而不必要求所有用户单独检查他们的用户名? 提前谢谢。 编辑 更多的一些代码示例(这里我只写相关的代码)。 用户: 带

  • 我正在尝试开发一个小型电子商务项目。我有一个篮子和篮子项目实体。我只是想当我为客户保存购物篮时,我想把购物篮项目保存在数据库中。我认为我不应该为篮子项目创建存储库。我应该能够保存篮子项目,同时使用篮子存储库保存篮子。 在这里,我试图通过篮子服务获得一个篮子项目,并将其设置为篮子实体并保存它。 我有什么问题?我有个例外。

  • 我是Hibernate的新手,并要求使用具有这些列的表的数据库 表:TBL _ product//库存项目列表< br >列:< br > key _ product < br > key _ category < br > fld _ product _ name < br > fld _ Inventory _ qty < br > fld _ unit _ price < br > fld

  • 我有一个问题,Spring数据没有保存实体。应用程序逻辑如下: 另一个应用程序正在监听负载相当重的Kafka主题(每秒数十条消息)并将消息插入数据库中具有“NEW”状态的表中。 @调度方法加载一个具有“NEW”状态的实体列表,这些实体被一个接一个地传输到FixedThreadPool(20个线程),它们的状态设置为“PROCESSING”和一个saveAll方法调用同一个表。 这两种日志方法都显示

  • 我在代码优先的情况下使用EF,我有这样的模型: 我收到一个客户ID和一个产品ID列表。当产品在数据库中不存在时,我想添加它: 问题是EF试图级联更改并尝试插入一个新的对象,其ID与现有对象相同,因此失败。我如何解决这个问题? 这是插入方法:

  • 在Spring Data JPA的“入门”示例中,我们创建了一个扩展CrudRepository的接口。但是,它只处理一个实体: 在现实世界的应用程序中,有许多实体(表),我们需要对它们进行CRUD操作。使用具有多个(相关或无关)实体的Spring数据JPA存储库的正确方法是什么? 我是否必须为每个实体创建接口并逐个自动连接它们(现在听起来这是一个非常疯狂的想法)?