2016-06-30 3 views
0

Zuerst zugeordnet subobject zu speichern, lassen Sie mir die damit verbundenen zwei Klassen beschreiben:One-to-One-träge mit optional laden = false, aber wie mit null

@Entity 
@Table(catalog = "db_consumer_master", name = "t_consumer") 
@PrimaryKeyJoinColumn(name = "id") 
public class Customer{ 
    @OneToOne(mappedBy = "customer", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = false) 
    public CustomerWallet getWallet() { 
     return wallet; 
    } 
} 


public class CustomerWallet { 
    @Id 
    @Column(name = "customer_id", unique = true, nullable = false) 
    @GeneratedValue(generator = "gen") 
    @GenericGenerator(name = "gen", strategy = "foreign", [email protected](name = "property", value = "customer")) 
    private long customerId; 
    private long amount; 

    @OneToOne 
    @PrimaryKeyJoinColumn 
    private Customer customer; 
} 

zu ermöglichen, träge laden, nur holen Einstellung = FetchType .LAZY funktioniert nicht, also füge ich "optional = false" hinzu, aber jetzt tritt ein neues Problem auf:

Ich möchte ein neues Anwalt-Objekt erstellen, indem ich session.save (Anwalt) aufruft. Hier ist der Code-Schnipsel einen Anwalt Instanz zu machen:

Customer customer= new Customer(); 
CustomerWallet wallet = new CustomerWallet(); 
customer.setWallet(wallet); 

wenn save (Kunde) aufgerufen wird, wird Ausnahme geworfen:

IdentifierGenerationException: versucht id von null zuweisen einer Eins-zu-Eins-Eigenschaft

Also, meine Frage ist, wie dieses Kundenobjekt mit Wallet-Objekt zu speichern ist hier null? Brieftasche benötigt eine Kunden-ID als den gemeinsamen Primärschlüssel als Zuordnung. aber wir werden diese Kundennummer erst erhalten, wenn der Kunde in der Datenbank festgehalten hat. Muss ich eine ID in Java anstelle eines Datenbanksystems generieren? Gibt es andere Möglichkeiten für diesen Fall?

+0

sollte nicht mappedBy 'customer' sein? und was ist Generator "Gen"? Ich denke, es sollte "fremd" sein – niceman

+0

Sie benötigen das Attribut Anwalt in Ihrer CustomerWallet-Klasse – cralfaro

+0

und ich denke '' PrimaryKeyJoinColumn' für Feld 'Kunde' in' CustomerWallet' ist falsch, weil es nicht der Primärschlüssel der 'CustomerWallet' Klasse – niceman

Antwort

0

zu ermöglichen, träge laden, nur holen Einstellung = FetchType.LAZY nicht funktioniert, so dass ich hinzufügen "optional = false"

Das optional Attribut nicht da ist ein träges Laden zu erzwingen. Es ist in der JPA 2.0-Spezifikation wie folgt definiert:

(Optional) Ob die Zuordnung optional ist. Wenn auf false festgelegt, muss immer eine Nicht-Null-Beziehung bestehen.

Und hier ist wie ein träges Laden in der Spezifikation angegeben ist:

(Optional) Ob der Verein sollte träge geladen werden oder müssen mit Spannung abgerufen werden. Die EAGER-Strategie ist eine Anforderung an die Laufzeit des Persistenzanbieters, dass die assoziierte Entität schnell abgerufen werden muss. Die LAZY-Strategie ist ein Hinweis auf die Laufzeit des Persistenzanbieters.

Das bedeutet, dass der Persistenzanbieter nicht verpflichtet ist, die zugehörige Entität zu laden.

Nun zu Ihrer Frage:

Also, meine Frage ist, wie dieses Kundenobjekt mit der Brieftasche Objekt speichern null, hier zu sein?

  1. Zunächst einmal definieren Ihre Zuordnungen richtig Sie verwenden PrimaryKeyJoinColumn Anmerkung über die Assoziation zu Customer. Diese Annotation wird verwendet, um eine Unterklasse mit ihrem übergeordneten Element in der Zuordnungsstrategie JOINED zu verknüpfen. Aber in Ihrem Fall haben Ihre Entitäten keine Vererbungsbeziehung.So müssen Sie stattdessen JoinColumn Anmerkung verwenden:

    @OneToOne 
    @JoinColumn(name = <name_of_foreign_key>) (Optional) 
    private Customer customer; 
    
  2. entfernen optional = false aus der @OneToOne Anmerkung im Customer Klasse.

  3. Ihre foreign key Spalte muss NULL Werte zulassen. Andernfalls erhalten Sie eine referentielle Contraint-Ausnahme.

+0

Vielen Dank an ujulu. Das Datenbankschema wurde mit hibernate4-maven-plugin aus Java-Klassen generiert, so dass der "name_of_foreign_key" bei jedem Generieren des Schemas geändert werden muss. Wie geht man in diesem Fall vor? – ylei

+0

Übrigens kann @PrimaryKeyJoinColumn verwendet werden, um eine shippingAddress in der User-Klasse als eine gemeinsame Primärschlüsselzuordnung zuzuordnen. Auszug aus dem Buch Seite Nr. 281. – ylei

+0

In diesem Fall ist 'JoinColumn' optional und Sie können es aus der Annotation entfernen (siehe den modifizierten Beitrag oben). Was die 'PrimaryKeyJoinColumn' betrifft, siehe [Hibernate-Dokumentation] (https://docs.jboss.org/hibernate/stable/annotations/reference/en/html_single). Übrigens habe ich dieses Buch nicht gelesen. – ujulu

Verwandte Themen