2013-05-06 80 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(); 
    } 
} 
相关问题