2012-08-15 60 views
4

在搜索完JPA文檔和各種帖子之後,我很困惑以下是否可以用JPA2.0。我剛剛開始與JPA,所以請原諒我,如果我做了一些愚蠢的事情,@ElementCollection with Map <Entity,Embeddable>其中Entity是Embeddable的字段

我的域模型有一個「投資組合」,其中包含零個或多個「未平倉頭寸」。一個職位由一個「工具」(這是一個JPA實體)和一個價格(雙重)組成。投資組合如下:

@Entity (name = "portfolio") 
public class Portfolio { 
    @Id 
    @Column (name = "id") 
    @GeneratedValue 
    private long id; 

    @ElementCollection (fetch = FetchType.EAGER) 
    @CollectionTable (name = "portfolio_entry", joinColumns = @JoinColumn (name = "portfolio_id")) 
    private final Map<Instrument, OpenPosition> positions = new HashMap<Instrument, OpenPosition>(); 
.... 

的OpenPosition嵌入如下:

@Embeddable 
public class OpenPosition extends Position { 
    @ManyToOne (targetEntity = InstrumentImpl.class, optional = false) 
    @JoinColumn (name = "instrument_id", nullable = false) 
    protected Instrument instrument; 

    @Column (name = "price", nullable = false) 
    protected double price; 
.... 

和儀器實體是:

@Entity (name="instrument") 
public class Instrument { 
    @Id 
    @Column(name = "id") 
    @GeneratedValue 
    private long id; 

    @Column(name = "isin", nullable = false) 
    private String isin; 
....  
    @Override 
    public int hashCode() { 
     int hash = 17; 
     hash = 31 * hash + isin.hashCode(); 
    .... 

當我嘗試使用此,該模式是創建,我可以堅持投資組合,但是當試圖檢索它們時,我在Instrument類的hashCode方法中得到一個NullPointerException。看起來JPA試圖獲取哈希代碼來構建Map鍵,但Instrument對象尚未加載。

我可以通過調試看到,儘管在Instrument對象中設置了id,但所有其他字段都爲null。

所以我的問題是,JPA2.0是否允許一個ElementCollection,其中的鍵是一個也作爲Embeddable值的字段存在的實體?如果是這樣,我搞砸了什麼。如果不是,最好的解決方法是使用Instrument實體的ID作爲密鑰嗎?

在此先感謝。

p.s.我正在使用hibernate 4.1.4 JPA實現。

+0

AFAIK你不能在Embeddable中使用實體。嵌入式應只包含基本類型。也不要在你的實體中使用'HashMap',而是使用'Map'接口。歡迎來到stackoverflow的方式;-) – siebz0r 2012-08-16 10:43:07

+0

@ siebz0r感謝您的反饋和歡迎。我相信JPA1.0中僅允許使用基本映射,但JPA2.0指出可嵌入對象允許所有關係 - 請參閱[鏈接](http://en.wikibooks.org/wiki/Java_Persistence/Embeddables#Relationships )。 Re:'Map' vs'HashMap',我不確定你的意思。該字段確實具有類型'Map',但是在實例化它時,我必須使用具體的類(即'HashMap') – pwrex 2012-08-16 13:20:44

回答

2

所以我的問題是,JPA2.0是否允許一個ElementCollection,其中的鍵是一個也作爲Embeddable值的字段存在的實體?

是的,我管理這個映射做到這一點:

@ElementCollection(targetClass = FreightBid.class) 
@MapKeyJoinColumn(name = "carrier_id", referencedColumnName = "id") 
@CollectionTable(name = "freight_bid", 
    joinColumns = @JoinColumn(name = "offer_pool_id")) 
@Access(AccessType.FIELD) 
private Map<Carrier,FreightBid> bidsByCarrier; 

在我的情況下,運營商是一個@Entity和FreightBid是@Embedded

我已經能夠保持和檢索正確包含此映射的實體。

我搞砸了什麼。

你應該從OpenPosition類中刪除領域protected Instrument instrument;,而使用註釋@MapKeyJoinColumn對投資組合類地圖領域申報至極列應作爲聯接列到地圖的關鍵。

此外,最好避免在對象的hashCode方法中使用除id之外的其他字段作爲映射鍵......您的JPA實現者可能會搞砸了。