2015-12-17 37 views
0

@ManyToOne引用非主鍵字段時,我發現了一個奇怪的行爲。@ManyToOne referencedColumnName到UniqueField但不是PrimaryKey

部分。 1個參考不PrimaryKey的

數據庫表:

Sessions 
ID number   (pk) 
SESSIONID varchar (unique, not null) 

History 
ID number   (pk) 
SESSIONID varchar (fk to Sessions.SESSIONID) 

Entityes:

@Entity 
@Table(name = "[email protected]_DB_LINK", schema = "ESAD_OWNER", 
uniqueConstraints = {@UniqueConstraint(columnNames = {"sessionid"})}) 
public class Sessions implements Serializable { 
    private static final long serialVersionUID = 1L;  
    @Id 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "ID") 
    private BigInteger id;  
    @Basic(optional = false) 
    @NotNull 
    @Size(min = 1, max = 40) 
    @Column(name = "SESSIONID", unique = true) 
    private String sessionid; 
    @OneToMany(mappedBy = "session", fetch = FetchType.LAZY) 
    private List<History> history; 
    ......... 
} 

@Entity 
    @Table(name = "[email protected]_DB_LINK", schema = "ESAD_OWNER") 
    public class History implements Serializable { 
    private static final long serialVersionUID = 1L;  
    @Id 
    @Basic(optional = false) 
    @NotNull 
    @Column(name = "ID") 
    private BigInteger id; 

    @ManyToOne 
    @JoinColumn(name = "SESSIONID", referencedColumnName = "SESSIONID") 
    private Sessions session; 
    .......... 
    } 

代碼:

List<History> hsLazy = sessions.getHistory();//Nothing select 
for (History hsLazy1 : hsLazy) { //*   
    System.out.println(hsLazy1.getId()); 
} 

* 一個選擇歷史WHERE SESSIONID =?

選擇工作階段WHERE SESSIONID = ?,中的子表中記錄歷史SELECT =計計數

PART.2參考PrimaryKey的

數據庫表:

Sessions 
ID number   (pk) 
SESSIONID varchar (unique, not null) 

History 
ID number   (pk) 
SESSIONID number(fk to Sessions.ID) 

實體:更改歷史記錄爲

@Entity 
@Table(name = "[email protected]_DB_LINK", schema = "ESAD_OWNER") 
public class History implements Serializable { 
    private static final long serialVersionUID = 1L;  
    .......... 
    @ManyToOne 
    @JoinColumn(name = "SESSIONID", referencedColumnName = "ID", 
               nullable=false) 
    private Sessions session; 
.......... 

代碼:

List<History> hsLazy = sessions.getHistory();//Nothing select 
for (History hsLazy1 : hsLazy) { //*   
    System.out.println(hsLazy1.getId()); 
} 

* ONE選擇史的SessionID

爲什麼休眠產生不同數量的查詢時@ManyToOne參考不PrimaryKey的和參考的PrimaryKey? 爲什麼這麼發生? 當沒有引用PK時,是否可以改變行爲?

P.S. JPA 2.0休眠4.2.5

+1

mmmm ...什麼?你能更清楚地解釋你問什麼? –

回答

0

在這兩種情況下與@ManyToOne協會你渴望提取Session對象爲每History。可能是,在第二種情況下(引用PrimaryKey)Hibernate從緩存中獲取Session對象,所以沒有任何額外的SQL查詢。 我的建議是改變抓取到懶人,並在需要時用join fetch(或其他方式)獲取Session

@ManyToOne(fetch = FetchType.LAZY) 
@JoinColumn(name = "SESSIONID", referencedColumnName = "SESSIONID") 
private Sessions session; 
+0

謝謝你的迴應。 – asu

0

Hibernate的一級緩存基於主鍵。

如果您使用主鍵作爲外鍵,則Hibernate可以直接從緩存中加載對象。

如果您使用輔助鍵作爲外鍵,那麼Hibernate不能使用第一級緩存並且必須查詢數據庫。

+0

謝謝你的迴應。將會考慮如何重新設計應用程序 – asu