HSQLDB detached entity passed to persist: server.Employee

Hallo zusammen,
ich bin für das Studium ein kleines Projekt (https://github.com/volker-raschek/world-of-codecraft-server) am realisieren. Es geht um einen Server und einen Client. Ich realisiere den Server und bin gerade dabei einen Testclient zu implementieren. Dem Client soll es möglich sein, neue Objekte zu erzeugen und ab zu fragen und hier hackt es.

Ich versuche momentan im Client was zu implementieren, dass der Client ein neues Objekt Employee oder Department erzeugt über den Server. Dieser soll das Object per Hibernate in eine MySQL Datenbank speichern. Bei dem Speicherprozess hängt es an der folgenden Zeile im Object CompanyManager
Code:
// EntityManager den neuen Datensatz übergeben, sodass Hibernate SQL ausführen kann
this.entityManager.persist(employee);
..
// EntityManager den neuen Datensatz übergeben, sodass Hibernate SQL ausführen kann
this.entityManager.persist(department);

Mit der Fehlermeldung
Code:
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: server.Employee

Mein Objekt Employee
Code:
package server;

import share.DepartmentInterface;
import share.EmployeeInterface;

import javax.persistence.*;
import java.rmi.RemoteException;
import java.time.LocalDate;
import java.util.Calendar;

/**
* Created by markus on 16.11.16.
*/
@Entity
@Table(name = "emp")
public class Employee implements EmployeeInterface{

    // Member Variablen
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "empno", length = 11, nullable = false)
    private int empNo;

    @Embedded
    @OneToOne (cascade=CascadeType.ALL, targetEntity=Department.class)
    @JoinColumn(name = "deptno", unique = false, nullable = true, updatable = true)
    private DepartmentInterface departmentInterface;

    @Column(name="salary", nullable = false)
    private double empSalary;

    @Column(name = "firstname", length = 50, nullable = false)
    private String empFirstName;

    @Column(name = "lastname", length = 50, nullable = false)
    private String empLastName;

    @Column(name="jobdescription", length = 150, nullable = true)
    private String empJobdescription;

    @Column(name="birthday", nullable = true)
    private Calendar empBirthday;

    @Column(name="birthplace", length = 50, nullable = true)
    private String empBirthplace;

    // Konstruktoren
    public Employee(int empNo, double empSalary, String empFirstName, String empLastName, String empJobdescription, Calendar empBirthday, String empBirthplace) {
        this.empNo = empNo;
        this.empSalary = empSalary;
        this.empFirstName = empFirstName;
        this.empLastName = empLastName;
        this.empJobdescription = empJobdescription;
        this.empBirthday = empBirthday;
        this.empBirthplace = empBirthplace;
    }

    public Employee(int empNo, DepartmentInterface departmentInterface, double empSalary, String empFirstName, String empLastName, String empJobdescription, Calendar empBirthday, String empBirthplace) {
        this.empNo = empNo;
        this.departmentInterface = departmentInterface;
        this.empSalary = empSalary;
        this.empFirstName = empFirstName;
        this.empLastName = empLastName;
        this.empJobdescription = empJobdescription;
        this.empBirthday = empBirthday;
        this.empBirthplace = empBirthplace;
    }

    public Employee() {
        super();
    }

    // Getter und Setter
    @Override
    public int getEmpNo() {
        return this.empNo;
    }

    @Override
    public void setEmpNo(int empNo) {
        this.empNo = empNo;
    }

    @Override
    @Embedded
    @OneToOne (cascade = CascadeType.ALL, targetEntity = Department.class)
    @JoinColumn( name = "DEPTNO", unique = false, nullable = true, updatable = true)
    public DepartmentInterface getDepartmentInterface(){
        return this.departmentInterface;
    }

    @Override
    public void setDepartmentInterface(DepartmentInterface departmentInterface){
        this.departmentInterface = departmentInterface;
    }

    @Override
    public String getEmpFirstName() {
        return this.empFirstName;
    }

    @Override
    public void setEmpFirstName(String empFirstName) {
        this.empFirstName = empFirstName;
    }

    @Override
    public String getEmpLastName() {
        return this.empLastName;
    }

    @Override
    public void setEmpLastName(String empLastName) {
        this.empLastName = empLastName;
    }

    @Override
    public Calendar getEmpBirthday() {
        return this.empBirthday;
    }

    @Override
    public void setEmpBirthday(Calendar empBirthday) {
        this.empBirthday = empBirthday;
    }

    @Override
    public String getEmpBirthplace() {
        return this.empBirthplace;
    }

    @Override
    public void setEmpBirthplace(String empBirthplace) {
        this.empBirthplace = empBirthplace;
    }

    @Override
    public double getEmpSalary() throws RemoteException {
        return this.empSalary;
    }

    @Override
    public void setEmpSalary(double empSalary) throws RemoteException {
        this.empSalary = empSalary;
    }

    @Override
    public String getEmpJobdescription() throws RemoteException {
        return this.empJobdescription;
    }

    @Override
    public void setEmpJobdescription(String empJobdescription) throws RemoteException {
        this.empJobdescription = empJobdescription;
    }


}

Mein Object Department
Code:
package server;

// Import von persistence Bibliothek
// Ist im Ordner resources/META-INF/persistence.xml definiert
import share.DepartmentInterface;
import share.EmployeeInterface;

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

/**
* Created by markus on 15.11.16.
*/
@Entity
@Table(name="dept")
public class Department implements DepartmentInterface {

    // Member Variablen
    @Id @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="deptno", length = 11, nullable = false)
    private int deptNo;

    @Column(name="deptname", length = 50, nullable = false)
    private String deptName;

    @Column(name="postcode", length = 5, nullable = false)
    private String deptPostalcode;

    @Column(name="location", length = 50, nullable = false)
    private String deptLocation;

    @Column(name="description", length = 150, nullable = true)
    private String deptDescription;

    @Transient
    private List<EmployeeInterface> emps;

    // Konstruktoren
    public Department(int deptNo, String deptName, String deptPostalcode, String deptLocation, String deptDescription) {
        super();
        this.deptNo = deptNo;
        this.deptName = deptName;
        this.deptPostalcode = deptPostalcode;
        this.deptLocation = deptLocation;
        this.deptDescription = deptDescription;
    }

    public Department() {
        super();
    }


    // Getter und Setter
    @Override
    public int getDeptNo() {
        return deptNo;
    }

    @Override
    public void setDeptNo(int deptNo) {
        this.deptNo = deptNo;
    }

    @Override
    public String getDeptName() {
        return deptName;
    }

    @Override
    public void setDeptName(String deptName) {
        this.deptName = deptName;
    }

    @Override
    public String getDeptStreet() {
        return null;
    }

    @Override
    public void setDeptStreet(String deptStreet) {

    }

    @Override
    public String getDeptPostalcode() {
        return deptPostalcode;
    }

    public void setDeptPostalcode(String deptPostalcode) {
        this.deptPostalcode = deptPostalcode;
    }

    @Override
    public String getDeptLocation() {
        return deptLocation;
    }

    @Override
    public void setDeptLocation(String deptLocation) {
        this.deptLocation = deptLocation;
    }

    @Override
    public String getDeptDescription() {
        return deptDescription;
    }

    @Override
    public void setDeptDescription(String deptDescription) {
        this.deptDescription = deptDescription;
    }

    @Override
    public void addEmp(EmployeeInterface employeeInterface)
    {
        emps.add(employeeInterface);
    }

    //diese Liste wird nicht in die Datenbank geschrieben
    @Override
    @Transient
    public List<EmployeeInterface> getEmployees() {
        return emps;
    }


}

Ganze Funktionen aus dem Object Company Manager, bei denen der Fehler auftritt
Code:
@Override
public EmployeeInterface addEmployee(int empNo, String empFirstName, String empLastName, Calendar empBirthday, String empBirthplace, String empJobdescription, double empSalary) throws RemoteException, AlreadyBoundException {
    // Öffnen der Transaktion, falls keine geöffnet ist
    if (!this.entityManager.getTransaction().isActive()) {
        this.entityManager.getTransaction().begin();
    }

    // Datensatz erstellen
    Employee employee = new Employee(
            empNo,
            empSalary,
            empFirstName,
            empLastName,
            empJobdescription,
            empBirthday,
            empBirthplace);

    // EntityManager den neuen Datensatz übergeben, sodass Hibernate SQL ausführen kann
    this.entityManager.persist(employee);

    // Datensatz flushen
    this.entityManager.flush();

    // Transaktion mit commit abschließen bzw. beenden
    this.entityManager.getTransaction().commit();


    // Department an Registry anmelden
    EmployeeInterface employeeInterface = (EmployeeInterface) UnicastRemoteObject.exportObject(employee, 0);

    // in Registry binden
    LocateRegistry.getRegistry().bind("e"+Integer.toString(employee.getEmpNo()), employeeInterface);


    // Rückgabe des Datensatzes
    return employee;
}

public DepartmentInterface addDepartment(int deptNo, String deptName, String deptDescription, String deptStreet, String deptPostalcode, String deptLocation) throws RemoteException, AlreadyBoundException {
    // Öffnen der Transaktion, falls keine geöffnet ist
    if (!this.entityManager.getTransaction().isActive()) {
        this.entityManager.getTransaction().begin();
    }

    // Datensatz erstellen
    Department department = new Department(deptNo,
            deptName,
            deptPostalcode,
            deptLocation,
            deptDescription);

    // EntityManager den neuen Datensatz übergeben, sodass Hibernate SQL ausführen kann
    this.entityManager.persist(department);

    // Datensatz flushen
    this.entityManager.flush();

    // Transaktion mit commit abschließen bzw. beenden
    this.entityManager.getTransaction().commit();



    // Department an Registry anmelden
    DepartmentInterface departmentInterface = (DepartmentInterface) UnicastRemoteObject.exportObject(department, 0);

    // in Registry binden
    LocateRegistry.getRegistry().bind("d"+Integer.toString(department.getDeptNo()), departmentInterface);



    // Rückgabe des Datensatzes
    return department;
}

Wo liegt hier das Problem, wie kann ich das lösen?
Viele Grüße
Volker
 

Joose

Top Contributor
Das Problem ist deine Beziehung zwischen den Beiden
https://notesonjava.wordpress.com/2008/11/03/managing-the-bidirectional-relationship/

Dein Employee kennt das Department und dein Department seine Employees, gut. Beim Employee ist dies aber keine OneToOne Relationship, dass würde bedeuten dass jedes Department ja nur einen Employee haben dürfte -> richtig wäre ein ManyToOne.
Dem Department hast du gar keine Informationen mitgegeben über die Beziehung, warum nicht?
 
Beim Employee ist dies aber keine OneToOne Relationship, dass würde bedeuten dass jedes Department ja nur einen Employee haben dürfte -> richtig wäre ein ManyToOne.
Das habe ich geändert. Ist mir nicht aufgefallen, vielen dank!

Dem Department hast du gar keine Informationen mitgegeben über die Beziehung, warum nicht?

Weil ich im Department eine Liste führe mit Employees
Code:
@Transient
private List<EmployeeInterface> emps;

Ist da ein Denkfehler drin? Wenn ja, wie müsste das richtig aussehen um die Beziehung zu realisieren?
Ich bin Einsteiger in Hibernate um das mal zu erwähnen :D

Viele Grüße
Volker
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
R Detached ResultSet Datenbankprogrammierung 3
torresbig MySQL hibernate - could not resolve entity class ... (Datenbank Anfänger) Datenbankprogrammierung 19
I Konzept: Klasse / Entity für Einstellung der Software Datenbankprogrammierung 3
J Netbeans 11 und Eclipse JPA 2.5 Entity wird nicht gefunden Datenbankprogrammierung 4
D MySQL Transaktionen in Entity-Class Datenbankprogrammierung 15
T Ebean Not an Entity Datenbankprogrammierung 1
H Entity in Java implementieren Datenbankprogrammierung 13
Y Entity must be managed to call remove Datenbankprogrammierung 1
F MySQL+ Netbeans: Datenbanken mit Automatisch generierten Entity Classes get und set Datenbankprogrammierung 2
T IllegalArgumentException: Person[ id=null ] is not a known entity type.??? Datenbankprogrammierung 0
R eclipselink - referenzierte Entity löschen Datenbankprogrammierung 0
Z ER Diagramm erstellen (Entity-Relationship) Datenbankprogrammierung 4
B Feld in einer @Entity als Text speichern Datenbankprogrammierung 5
K Entity-Klassen generieren Datenbankprogrammierung 4
D Datenbank Entity Datenbankprogrammierung 3
C Hibernate Liste mit allen Objekten einer Entity Datenbankprogrammierung 17
T org.hibernate.MappingException: entity class not found Datenbankprogrammierung 4
D org.hibernate.MappingException: Unknown entity mit Annotations Datenbankprogrammierung 9
P Hibernate -> SQL verwenden und keine Entity Datenbankprogrammierung 19
M Problem mit @Entity Datenbankprogrammierung 18
R JPA, Spring, löschen einer Entity Datenbankprogrammierung 2
P Neues Attribut in Entity-Klasse Datenbankprogrammierung 3
G Entity Realtionship Model erstellen Datenbankprogrammierung 11
QDog JPA: Entity "laden" und später updaten Datenbankprogrammierung 4

Ähnliche Java Themen


Oben