3

我在处理 mysql 表的映射对象关系时遇到问题。我有 2 个表格,如下所示:

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

}

这对我有用,但我想在表中使用复合键,deviceId和。packageNameApkInfos

@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 Data JPA 存储库保存实体时,出现错误:

org.springframework.dao.InvalidAccessApiUsageException: Class不能为null,嵌套异常是java.lang.IllegalArgumentException: Class不能为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”已经存在于设备表中。

4

1 回答 1

6

我创建了一个单独的主键类,在 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 和覆盖 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();
   }
}
于 2013-05-06T03:43:48.227 回答