gpt4 book ai didi

java - JPA 对象引用未保存的 transient 实例 - 在刷新之前保存 transient 实例

转载 作者:行者123 更新时间:2023-12-01 09:38:49 25 4
gpt4 key购买 nike

我很难调试为什么 JPA 不级联我的 @ManyToMany 关系。我发现的所有答案都与缺少级联语句有关。但我确实拥有它们并且仍然得到:

Caused by: org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.example.iaa.model.Employee

代码基于本教程:https://hellokoding.com/jpa-many-to-many-relationship-mapping-example-with-spring-boot-maven-and-mysql/

package com.example.iaa.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.iaa.model.Employee;

public interface EmployeeRepository extends JpaRepository<Employee, Integer> {
}




package com.example.iaa.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import com.example.iaa.model.Role;

public interface RoleRepository extends JpaRepository<Role, Integer> {
}




package com.example.iaa.model;

import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table//(name = "role")
public class Role {

@Id
@GeneratedValue
private int id;

private String name;

@ElementCollection
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable//(name = "employee_role", joinColumns = @JoinColumn(name = "id_role", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "id_employee", referencedColumnName = "id"))
private Set<Employee> employees;

public Role(String name, HashSet<Employee> employees) {
this.name = name;
this.employees = employees;
}

public Role(String name) {
this.name = name;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Set<Employee> getEmployees() {
return employees;
}

public void setEmployees(Set<Employee> employees) {
this.employees = employees;
}

}




package com.example.iaa.model;

import java.util.Collections;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.ElementCollection;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

@Entity
@Table//(name = "employee")
public class Employee {

@Id
@GeneratedValue
private int id;

private String firstName;
private String lastName;

@ElementCollection
@ManyToMany(cascade = CascadeType.ALL)
@JoinTable//(name = "employee_role", joinColumns = @JoinColumn(name = "id_employee", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "id_role", referencedColumnName = "id"))
private Set<Role> roles;

public Employee(String firstName) {
this.firstName = firstName;
}

public Employee() {
roles = new HashSet<Role>();
}

public Employee(String name, HashSet<Role> roles) {
this.firstName = name;
this.roles = roles;
}

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getDisplayName() {
return firstName + " " + lastName;
}

public String getFirstName() {
return firstName;
}

public void setFirstName(String firstName) {
this.firstName = firstName;
}

public String getLastName() {
return lastName;
}

public void setLastName(String lastName) {
this.lastName = lastName;
}

public void addRole(Role role) {
roles.add(role);
}

public Set<Role> getRoles() {
return Collections.unmodifiableSet(roles);
}

public void setRoles(Set<Role> roles) {
this.roles = roles;
}

public boolean hasRole(Role role) {
return roles.contains(role);
}

@Override
public String toString() {
String ret = "";
ret += "id: " + id + "\n";
ret += "firstName: " + firstName + "\n";
ret += "lastName: " + lastName + "\n";
ret += "displayName: " + getDisplayName() + "\n";
ret += "roles: ";

String delim = "";
for (Role role : roles) {
ret += delim + role;
delim = ",";
}
return ret;
}
}




package com.example.iaa.controller;

import java.util.HashSet;

import javax.transaction.Transactional;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

import com.example.iaa.model.Employee;
import com.example.iaa.model.Role;
import com.example.iaa.repository.EmployeeRepository;
import com.example.iaa.repository.RoleRepository;

public class HelloJpaApplication {
private static final Logger logger = LoggerFactory.getLogger(HelloJpaApplication.class);

@Autowired
private RoleRepository roleRepository;

@Autowired
private EmployeeRepository employeeRepository;

@RequestMapping(value = "/jpa")
@Transactional
public String testJPA(final Model model) throws Exception {
// save a couple of roles
final Employee employeeA = new Employee("Employee A");
final Employee employeeB = new Employee("Employee B");
final Employee employeeC = new Employee("Employee C");

roleRepository.save(new HashSet<Role>(){{
add(new Role("Role A", new HashSet<Employee>(){{
add(employeeA);
add(employeeB);
}}));

add(new Role("Role B", new HashSet<Employee>(){{
add(employeeA);
add(employeeC);
}}));
}});

// fetch all roles
for(Role role : roleRepository.findAll()) {
logger.info(role.toString());
}

// save a couple of employees
final Role roleA = new Role("Role A");
final Role roleB = new Role("Role B");

employeeRepository.save(new HashSet<Employee>() {{
add(new Employee("Employee A", new HashSet<Role>() {{
add(roleA);
add(roleB);
}}));

add(new Employee("Employee B", new HashSet<Role>() {{
add(roleA);
add(roleB);
}}));
}});

// fetch all employees
for(Employee employee : employeeRepository.findAll()) {
logger.info(employee.toString());
}
return "soy:iaa.index";
}
}

最佳答案

正如链接中给出的,我在下面进行了更改

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
@JoinTable(name = "employee_role", joinColumns = @JoinColumn(name = "id_employee", referencedColumnName = "id"), inverseJoinColumns = @JoinColumn(name = "id_role", referencedColumnName = "id"))
private Set<Employee> employees;

@ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "employees")
private Set<Role> roles;

还添加了默认构造函数和急切获取,然后它就起作用了。

关于java - JPA 对象引用未保存的 transient 实例 - 在刷新之前保存 transient 实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38618410/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com