2013-08-17 6 views
6

Ich benutze Frühling 3.2.3 und Hibernate 4.2.3 und JDK 7.Objekt verweist auf eine nicht gespeicherte transiente Beispiel: wie spülen oder Rückkehr gespeichert Objekt

Ich habe eine einfache Einheit:

@Entity 
public class Language { 
    @Id 
    @GeneratedValue 
    private long id; 

    @Column(nullable = false, length = 3, unique = true) 
    private String code; 
} 

I eine Instanz dieser Entität sparte @Service kommentierte Klasse mit einer @Transactional kommentierten Methode, die eine DAO verwendet, die das Unternehmen spart mit

sessionFactory.getCurrentSession().save(object); 

Danach benutze ich d die gespeichertLanguage Einheit für EntityX zu schaffen, die es in einer ManyToOne Beziehung verwendet ...

lang=new Language(); 
// ... 
languageService.saveLanguage(lang); 
e=new EntityX(); 
// ... 
e.setLanguage(lang); 
otherService.saveEntity(e); 

und EntityX ist definiert als ...

@Entity 
public class EntityX { 
    @ManyToOne 
    @JoinColumn(nullable = false) 
    private Language language; 
     // ... 
} 

ich die Ausnahme immer bekommen

Ich versuche einige Cascade-Definitionen in EntityX ' s Beziehung zu Language wie in anderen Posts vorgeschlagen, aber es hat keine Wirkung.

Wenn ich die gespeicherte Language Entität neu lade, indem ich sie durch seine code mit einigen HQL-Abfrage finden, dann funktioniert alles gut, aber das ist weit weg von "nett".

Leider gibt die save(...) Methode (n) von org.hibernate.Session das gespeicherte Objekt nicht zurück.

Hat jemand irgendwelche Ideen, wie man es löst?

Antwort

5

Ist Sie Code in einem einzigen @Transactional Methode?
Wenn nicht, kann das Problem sein, dass nach jedem Aufruf der Service-Methode Transaktion Commit und Sitzung gelöscht wird. Wenn Sie versuchen, eine Entität zu speichern, wird das Sprachobjekt in der Sitzung nicht erkannt und als vorübergehende Instanz verwaltet und gibt den Fehler aus.

Wenn Ihr Code unter einer einzigen Transaktion ist, haben Sie versucht, eine flush() vor dem Speichern der Entität zu erzwingen Hibernate Store Language in die Datenbank und zuweisen Sie eine gültige @Id Entifikator?

Nachdem alle - IMHO - wenn Sie eine Abhängigkeit von Entity und Sprache die beste Wahl ist:

@ManyToOne(cascade = CascadeType.ALL) 
private Language language; 

und Ihren Code ändern:

e=new EntityX(); 
Language lang = new Language(); 
// ... 
e.setLanguage(lang); 
otherService.saveEntity(e); 

und Sie brauchen nicht zu Persistenz der Entität in zwei Schritten (Sprache + Entität); Sprache + Entität als einzelnes Element verwalten

PS: Die Speichermethode (n) von org.hibernate.Session gibt das gespeicherte Objekt nicht zurück, da das Objekt gleich bleibt (Referenz nicht) ändern), nur Objekteigenschaften Änderungen (wie zum Beispiel die markierte @Id)!

EDIT:
Machen Sie ein Objekt persistent (session.save() it ich meine) führen nicht zu einer sofortigen einfügen/aktualisieren; ohne Kaskadenhinweis Hibernate-Look erkennt keine Abhängigkeit zwischen EntityX und Language und führt keine SQL-Einfügung von Language vor dem Speichern von EntityX durch.
spracheService.save (sprache) call führt session.flush() nicht durch, weil sie unter demselben @Transactional sind und ohne session.commit() wird session.flush() ausgeführt und die beste option ist, dass das Language object immer noch als markiert ist vorübergehend.
Sie können eine Überprüfung durchführen: Dienste extrahieren Code speichern (Sprache entityX) und alle in einzelne @Transactional setzen und prüfen, ob Hibernate Ihnen immer noch Fehler gibt.
Meine beste Option ist immer noch eine flush() in der Mitte oder ändern Sie Ihre Zuordnung, keine andere Möglichkeit

+0

Der Code ist in einer einzigen "@ Transactional" -Methode. Die Service-Methoden sind auch '@ Transactional', aber sie erfordern keine neue Transaktion, also nehme ich an, dass die existierende verwendet wird. Ich habe Sprache für sich selbst gespeichert, weil ich eine Spracheinheit und viele EntityX habe und jede von ihnen die gleiche Spracheinheit verwendet. – t777

+1

überprüfen Sie meine Bearbeitung, zu lang für einen Kommentar. Ich hoffe klar zu sein, Englisch ist nicht meine Muttersprache, sorry –

+0

Hallo @LucaBassoRicci, ich habe das gleiche Problem, aber meine Technologie ist anders, können Sie einen Blick darauf werfen .. http://StackOverflow.com/Questions/28279304/error-when-saving-a-object-welche-hat-fremde-key-object-references-an-unsaved –

2

Erstens, wenn das code Feld der Primärschlüssel (oder Sie sind es zumindest als primäre ID für Hibernate), geben @Id:

@Id 
@GeneratedValue(generator="assigned") 
@Column(length = 3) 
private String code; 

Nicht eine ID-Spalte Angabe könnte Hibernate verwirrend ein bisschen; zitieren Sie mich nicht darauf.

Wenn save() noch nicht danach funktioniert, können Sie merge() verwenden:

Language lang = new Language("XYZ"); 
lang = session.merge(lange); 
+0

Es tut mir leid. Ich habe meinen Code zu sehr gekürzt. Es gibt ein ID-Feld. Ich habe es dem Code meines Beitrags hinzugefügt. Ich habe das gleiche Problem, wenn ich merge statt speichern. – t777

Verwandte Themen