2009-08-26 15 views
2

Ich habe eine Datenbank, die verschiedene Arten von Beziehungen basierend auf Daten haben kann, die während der letzten Geschäftstransaktion aktualisiert wurden. Ein Beispiel wäre in einer Anwendung zum Schreiben von Richtlinien. Die Haupttabelle enthält allgemeine Richtlinieninformationen und es gibt verwandte Tabellen, die Informationen wie die Informationen des Agenten und die Informationen des Versicherten enthalten. Wenn die erste Transaktion ausgegeben wird, werden alle Tabellen aufgefüllt. Bei nachfolgenden Transaktionen werden jedoch nur die Tabellen mit Aktualisierungen in der Datenbank beibehalten. Ich versuche nun, Klassen zu erstellen, die JPA implementieren und die Beziehungen zwischen den Tabellen eins zu eins definieren. Ich möchte dann benutzerdefinierte Ladeprogramme für jede der Beziehungen implementieren, um sicherzustellen, dass ich jedes Mal, wenn ich die Richtlinieneinheit abrufe, in der Lage bin, die neueste Version der entsprechenden Tabellen abzurufen. Weiß jemand, wie man diese Logik implementiert? Ich habe versucht, @NamedNativeQuery zu verwenden und HQL zu verwenden, aber in beiden Fällen sagt es mir, dass ein Spaltenname, den ich spreche, nicht existiert.Benutzerdefinierte OneToOne Hibernate/JPA Association

Jede Hilfe wäre sehr willkommen.

Code wurde unten zur Verfügung gestellt, um zu veranschaulichen, was ich mache.

@Entity 
@NamedNativeQuery(name = "loadLatestBilling", 
        query = "Select {i.*} from TransactionSummary as ts outer join BillingInfo i on i.systemAssignId=ts.systemAssignId where ts.systemAssignId=:systemAssignId and i.transSeqNo<=:transSeqNo order by i.systemAssignId, i.transSeqNo DESC", 
        resultClass = BillingInfo.class) 

public class CoTransactionSummary implements java.io.Serializable, 
    CdbCoTransactionSummary { 


@OneToOne(targetEntity = BillingInfo.class, fetch = FetchType.LAZY) 
@org.hibernate.annotations.NotFound(action = org.hibernate.annotations.NotFoundAction.IGNORE) 
@Loader(namedQuery = "loadLatestBilling") 
public BillingInfo getBillingInfo() { 
    return billingInfo; 
} 

public void setBillingInfo(BillingInfo billingInfo) { 
    this.billingInfo= billingInfo; 
} 

}

Im obigen Beispiel würde die SystemAssignId zu dieser Einheit gehör zwischen allen Datensätzen gemeinsam sein. Die transSeqNo würde für jede nachfolgende Transaktion inkrementiert und somit würde der benutzerdefinierte Lader nach dem höchsten Wert suchen, der mit systemAssignId assoziiert ist.

Vielen Dank für Ihre Unterstützung.

Antwort

2

Ihre benannte Abfrage ist falsch - Sie können keine benannten Parameter darin haben. Sie können nur einen Positionsparameter haben, der durch den Primärschlüsselwert ersetzt wird (gut, es müssen möglicherweise mehr als eins für zusammengesetzte IDs sein, aber das trifft in Ihrem Fall nicht zu). Ich glaube auch nicht, dass es legal ist, mehr als einen Wert zurückzugeben; obwohl Hibernate es möglicherweise gleiten lässt.

Jetzt, da die Abfrage von PK (BillingInfo PK) basiert sein muss, wird es nicht einfach sein, das, was Sie wollen, über Eins-zu-eins-Zuordnung zu tun (es sei denn, Sie beabsichtigen natürlich, Ihre CoTransactionSummary alle zu aktualisieren Zeit, um auf eine entsprechende BillingInfo zu zeigen, aber in diesem Fall brauchen Sie nicht alle diese benutzerdefinierten Laden Zeug). Sie müssen im Grunde Ihre Abfrage neu schreiben, um BillingInfo Tabelle zweimal zu verbinden - zum ersten Mal TransactionSummary PK von BililngInfo Rekord mit PK von Hibernate und das zweite Mal, um den neuesten BillingInfo Datensatz zu erhalten. Die ganze Sache scheint ziemlich chaotisch.

Verwenden Sie stattdessen one-to-many Zuordnung (Sie können immer BillingInfo Sammlung privat machen und nur die entsprechende Instanz über öffentliche getBillingInfo() Methode offen legen).