2013-10-26 9 views
8

Ich versuche, eine Person pojo zu mysql einfügen db mit Hibernate EntityManager Methode bestehen,Hibernate Ausnahme: frei stehende Einheit übergeben beharren

entityManagerTransactionService.getEntityManager().persist(TemplateObject); 

und diese Ausnahme erhalten,

javax.persistence.PersistenceException: 
org.hibernate.PersistentObjectException: detached entity passed to 
persist: com.esupu.base.model.pojo.common.TitleType at 
org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1387).... 

und dort mehr ist ..

Caused by: org.hibernate.PersistentObjectException: detached entity 
passed to persist: com.esupu.base.model.pojo.common.TitleType at 
org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:141) 
    at 
org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:843) 

Meine Person.java Klasse ist,

@Entity 
public class Person extends TemplateObject { 

    @OneToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST,CascadeType.REFRESH }) 
     private TitleType titleType; 
     private String middle; 
     private String last; 
     @OneToOne(cascade = { CascadeType.ALL }) 
     private Address address; 
     private Date birthdate; 
     private String email; 
     private String telephone; 
     private String fax; 
     @OneToOne(cascade = { CascadeType.ALL }) 
     private Location location; 
     @OneToOne(cascade = { CascadeType.ALL }) 
     private Country country; 

und dann die Getter Setter-Methoden des pojo ..

der Fehler TitleType Klasse zu werfen ist ein "public static final" title Typ-Definition-Anbieter,

@Entity 
public class TitleType extends TemplateObject { 

    /** 
    * 
    */ 
    private static final long serialVersionUID = 3104954552111621034L; 

    private TitleType(int id, String name) { 
     setId(id); 
     setName(name); 
    } 

    public static final TitleType MR = new TitleType(1, "Mr"); 
    public static final TitleType MISS = new TitleType(2, "Miss"); 
    public static final TitleType MRS = new TitleType(3, "Mrs"); 
    public static final TitleType MS = new TitleType(4, "Ms"); 
    public static final TitleType DOCTOR = new TitleType(5, "Doctor"); 
    public static final TitleType PROFESSOR = new TitleType(6, "Professor"); 
    public static final TitleType SIR = new TitleType(7, "Sir"); 
    public static final TitleType MADAM = new TitleType(8, "Madam"); 

} 

Ich gründe die title type Klasse für die Person als,

ist es unmöglich, eine öffentliche statische final type definierte Klasse an Hibernate zu übergeben? oder gibt es irgendetwas, was ich falsch mache?

Vielen Dank im Voraus

+0

zeigen uns, Code, um das Objekt zu bestehen. Es scheint, dass Sie versuchen, ein losgelöstes Objekt zu bestehen – Shamse

Antwort

15

Die Objekte, die Sie versuchen, zu bestehen sind TitleType, die nicht ID Werte haben sollten. Andernfalls überprüft Hibernate, ob das Objekt im Sitzungskontext persistent oder getrennt ist. Wenn Sie einige Felder Ihres Objekts nicht so beibehalten möchten, können Sie die Annotation @Transient verwenden, um diese Felder aus der Feldzuordnung auszuschließen, wenn die Entität beibehalten wird. Das ist nicht gut, IDs in den DAOs oder Entities fest zu codieren, da diese Werte von einem Generator generiert werden könnten. Wenn Sie die Datenbank manuell mit diesen Konstanten aktualisieren, können Sie diese IDs jedoch als Konstanten im Code definieren und Objekte von Sitzung zu ID laden bevor Sie die vorübergehende oder persistente Instanz initialisieren.

11

Statt dies zu tun: public static final TitleType MR = new TitleType(1, "Mr");

Sie sollten die EntityManager verwenden, das Objekt zu holen. Andernfalls wird Hibernate bemerken, dass dieses Objekt (mit der ID 1) bereits gespeichert ist, aber da Sie es nicht geladen haben, hat der Entity Manager es nicht in seiner eigenen Sammlung -> das ist eine losgelöste Entität.

Also, sollten Sie tun:

TitleType MR = em.find(TitleType.class, 1); 
Person p = new Person(...); 
p.setTitleType(MR); 

em.merge(p); 
+0

Ich testete und finden Sie heraus, dass Ihre Antwort funktioniert auch korrekt, aber ich wählte die ID von TitleType DAO als Nikkon vorgeschlagen, so musste ich seine Antwort als die akzeptierte wählen, viele Danke für die Hilfe für Sie beide :) –

+0

Dies ist ein schmutziger Ansatz, weil dies Controller-Level-Code mit Persistenz-Layer-Code mischt. – CodeMed

+2

@CodeMed Nein, ist es nicht. Das Beispiel ist ziemlich kurz ja, aber es ist der Weg zu gehen. Wenn Sie einen neuen Benutzer zu einer Gruppe hinzufügen möchten, müssen Sie auch die vorhandene Gruppe laden, den neuen Benutzer hinzufügen und schließlich Ihre Änderungen in die Datenbank übertragen, ohne die vorhandene Gruppe zu berühren. – dognose

Verwandte Themen