2013-05-06 28 views
2

我有一個問題來處理mysql表的映射對象關係。 我有如下2個表:如何使用JPA2和Spring Data JPA中的關係處理複合鍵?

Device 
----------- 
deviceId PK 
deviceName 

ApkInfo 
-------- 
id PK 
packageName 
appName 
deviceId FK 

然後這裏有我的課:

@Entity 
@Table(name="Device") 
public class Device implements Serializable { 

    @Column 
    @Id 
    private String deviceId; 

    @Column 
    private String deviceName; 

    //getters and setters 

} 


@Entity 
@Table(name="ApkInfos") 
public class ApkInfo implements Serializable { 

    @Column 
    @Id 
    @GeneratedValue(strategy=GenerationType.AUTO) 
    private int id; 

    @Column 
    @Id 
    private String packageName; 

    @Column 
    private String appName; 

    @Column 
    @Temporal(TemporalType.TIMSTAMP) 
    private Date installDate; 

    @ManyToOne 
    @JoinColumn(name="deviceId" referencedColumnName="deviceId") 
    private Device device; 

    //getters and setters 

} 

這對我的作品,但我想用複合鍵,deviceIdpackageName,在ApkInfos表。

@Entity 
@Table(name="ApkInfos") 
public class ApkInfo implements Serializable { 

    @Colum(instable=false, updatable=false) 
    @Id 
    private String deviceId; 

    @Column 
    private String packageName; 

    @Column 
    private String appName; 

    @ManyToOne 
    @JoinColumn(name="deviceId" referencedColumnName="deviceId") 
    private Device device; 

    //getters and setters 

} 

但是,當我試圖挽救使用Spring數據JPA庫的實體,我得到了一個錯誤:

org.springframework.dao.InvalidAccessApiUsageException: Class must not be null, nested exception is java.lang.IllegalArgumentException: Class must not be null

ApkInfo apkInfo = new ApkInfo(); 
apkInfo.setDeviceId("1234"); 
apkInfo.setPackageName("aaa"); 
apkInfo.setAppName("myapp"); 
apkInfo.setInstallDate(new Date()); 
apkInfo.setDevice(new Device("1234")); 

repository.save(apkInfo); 

而且設備具有deviceID「1234」已經存在於器表。

+0

你可以在這裏找到解釋有關複合鍵: http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#d0e2177 – Alex 2013-05-06 02:00:19

+0

我看了,但仍是不對我清楚。 – sunghun 2013-05-06 02:41:11

+0

爲您的複合ID創建單獨的類(它將成爲您的主鍵),然後在您的主類中使用批註'@EmbeddedId'而不是'@Id'來使用它。 – Alex 2013-05-06 03:03:46

回答

5

我在ApkInfo類中添加了一個單獨的主鍵類@IdClass。它現在工作正常,謝謝。我將在稍後查看EmbeddedId。

我在實體類中添加了@IdClass,在packageName屬性中添加了@Id。此外,我做了插入,更新一對多列的錯誤。

@Entity 
@Table(name="ApkInfos") 
@IdClass(ApkInfo.class) 
public class ApkInfo implements Serializable { 

    @Column @Id private String deviceId; 
    @Column @Id private String packageName; 

    @ManyToOne 
    @JoinColumn(name="deviceId" referencedColumnName="deviceId", insetable=false, updatable=false) 
    private Device device; 


    //getters and setters missing 
} 

主鍵類只有setter和overrides equals和hasCode方法。

public class ApkInfo implements Serializable { 

    private String deviceId; 
    private String packageName; 


    public ApkInfo(){} 
    public ApkInfo (String deviceId, String packageName){ 
     this.deviceId = deviceId; 
     this.packageName = packageName; 
    } 

    public String getDeviceId(){ 
     return this.deviceId; 
    } 

    public String getPackageName(){ 
     return this.packageName; 
    } 

    @Override 
    public boolean equals(Object obj){ 
     return (obj!=null && 
       obj instanceof ApkInfoPk && 
       deviceId.equals(((ApkInfoPk)obj).getDeviceId()) && 
       packageNames.equals(((ApkInfoPk)obj).getPackageName())); 
    } 

    @Override 
    public int hashCode(){ 
     super.hashCode(); 
    } 
} 
相關問題