2015-08-25 11 views
5

Oft verwende ich @Formula in meinen Entitäten. Aber es war immer eine einfache Abfrage oder eine gespeicherte Prozedur mit Parametern, die ich aus der Tabelle ablegen kann. Jetzt muss ich eine Eigenschaft von einem verwandten Objekt verwenden. Aber ich sehe Ausnahme, wenn Sie versuchen, ein Objekt von DB zu bekommen. Bitte beachten Sie ein Beispiel unterWie Entity-Feld in Hibernate @Formula verwenden

@Entity 
@Table(name = "MINISTRY") 
public class Ministry { 

    @Id 
    @Column(name = "ID") 
    private Long id; 

    @Column(name = "NAME") 
    private String name; 

    // unnecessary code 

} 

@Entity 
@Table(name = "DEPARTMENT") 
public class Department { 

    @Id 
    @Column(name = "ID") 
    private Long id; 

    @Column(name = "DEP_NAME") 
    private String departmentName; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "MINISTRY_ID") 
    private Ministry ministry; 

    // unnecessary code 
} 

@Entity 
@Table(name = "EMPLOYEE") 
public class Employee { 

    @Id 
    @Column(name = "ID") 
    private Long id; 

    @ManyToOne(fetch = FetchType.LAZY) 
    @JoinColumn(name = "DEPARTMENT_ID") 
    private Department department; 

    @Formula("test_package.calc_something(department.ministry.id)") 
    private BigDecimal someMetric; 

    // unnecessary code 

} 

Wie sollte ich Einheit prop in @Formula verwenden. Ich will nicht so etwas wie

select d.ministry.id from Department d ... 

Antwort

5

schreiben Wenn Sie die JavaDoc von Formula lesen Sie sehen:

Die Formel hat ein gültiges SQL-Fragment

So wurden Sie müssen SQL verwenden wie:

Das einzige, was von Hibernate im Fragment geändert wird, bevor es in SQL geschrieben wird: Es fügt den Spalten den Tabellenalias hinzu (wie Sie das nicht vorhersagen können). Ich erwähne das, weil nur ein rudimentärer SQL-Parser dafür verwendet wird, der den Alias ​​an falschen Positionen für komplexere Fragmente einfügt.

Eine Bemerkung über die Leistung: Die Formel für jede Department Einheit ausgeführt wird, die Sie selbst laden, wenn Sie nur das Attribut zum Sortieren oder Filtern verwendet werden sollen (nur aus dem Namen des Attributs zu erraten) - es sei denn, Sie verwenden @Basic(fetch = FetchType.LAZY) und schalten Bytecode Instrumentierung on (oder emulieren, dass mit FieldHandled).

+0

Vielen Dank für Ihre Antwort. Aber ich habe schlechtes Beispiel geschrieben. Aufgabe ist es, die Parameter der zugehörigen Objekte zu übernehmen. Ich habe das Beispiel aktualisiert. Danke im Voraus. – Dmitry