簡體   English   中英

JPA對象引用了未保存的瞬態實例-在刷新之前保存瞬態實例

[英]JPA object references an unsaved transient instance - save the transient instance before flushing

我很難調試JPA為什么不級聯我的@ManyToMany關系。 我發現的所有答案都與缺少級聯語句有關。 但是我確實有它們並且仍然得到:

由以下原因引起:org.hibernate.TransientObjectException:對象引用了一個未保存的瞬態實例-在刷新之前保存該瞬態實例: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;

還添加了默認構造函數並渴望獲取,然后它起作用了。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM