0

我有这种情况:我将 JPA 与 Hibernate 一起使用,我想从数据库中获取一些数据。不幸的是,我有两组不同的独特约束。我的数据库表中有一个,而我的 java 实体中的另一个略有不同。我无法在 DB 中更改一个,因为我无法访问那里,我也无法在 java Entity 中更改一个,因为它可能会在我的应用程序的其他部分产生错误。

在 Oracle 数据库中,我有表Foo。在里面我有两个类似的记录:

桌子

我的 Java 实体根据参数决定记录是否唯一:

  1. 项目清单
  2. ACC_ID
  3. PLACE_ID
  4. INSTALLATION_ID
  5. DISM_DATE
  6. BOX_ID
  7. FOO_ID
  8. ACC_START_DATE

因此,在我基于 Foo Entity 执行休眠选择查询后,我只会从数据库中获取一条记录(因为 java 认为 db 中的两个 foo 是相同的)

没关系(我更喜欢一个结果),但我能以某种方式指定我最后会得到这两条记录中的哪一条吗?假设在这种情况下,我想获得一个 ACTIVITY_FLAG = 'Y' (不是表中的第一个,不是随机的,也不是最新的)。这可能吗?

现在我使用 @Embeddable 和 @IdClass 注解在 Java 代码中设置唯一参数:

Foo.java 类:

@Entity
@Table(name = "Foo")
@IdClass(FooPK.class)

public final class Foo {

   private Long       rowId;
   private Long       boxId;
   private Integer    fooNumber;
   private String     description;
   private BigDecimal upperReadoutDate;
   private BigDecimal upperReadoutDate;
   private String     activityFlag;
   private Long       accId;
   private Long       placeId;
   private Long       installationId;
   private Date       dismountingDate;
   private Date       accStartDate;

   @Id
   @Column(name = "FOO_ID")
   public Integer getFooNumber() {
      return fooNumber;
   }

   public void setFooNumber(Integer mFooNumber) {
      fooNumber = mFooNumber;
   }

   @Column(name = "DESCRIPTION")
   public String getDescription() {
      return description;
   }

   public void setDescription(String mDescription) {
      description = mDescription;
   }

   @Column(name = "D_READ_DATE")
      public BigDecimal getLowerReadoutDate() {
      return lowerReadoutDate;
   }

   public void setLowerReadoutDate(BigDecimal mLowerReadoutDate) {
      lowerReadoutDate = mLowerReadoutDate;
   }

   @Column(name = "U_READ_DATE")
   public BigDecimal getUpperReadoutDate() {
      return upperReadoutDate;
   }

   public void setUpperReadoutDate(BigDecimal mUpperReadoutDate) {
      upperReadoutDate = mUpperReadoutDate;
   }

   @Column(name = "ACTIVITY_FLAG")
   public String getActivityFlag() {
      return activityFlag;
   }

   public void setActivityFlag(String mActivityFlag) {
      activityFlag = mActivityFlag;
   }

   @Id
   @Column(name = "BOX_ID")
   public Long getBoxId() {
      return boxId;
   }

   public void setBoxId(Long mBoxId) {
      boxId = mBoxId;
   }

   @Column(name = "ROW_ID")
   public Long getRowId() {
      return rowId;
   }

   public void setRowId(Long mRowId) {
      rowId = mRowId;
   }

   @Id
   @Column(name = "ACC_ID")
   public Long getAccId() {
      return accId;
   }

   public void setAccId(Long mAccId) {
      accId = mAccId;
   }

   @Id
   @Column(name = "PLACE_ID")
   public Long getPlaceId() {
      return placeId;
   }

   public void setPlaceId(Long mPlaceId) {
      placeId = mPlaceId;
   }

   @Id
   @Column(name = "INSTALLATION_ID")
   public Long getInstallationId() {
      return installationId;
   }

   public void setInstallationId(Long mInstallationId) {
      installationId = mInstallationId;
   }

   @Id
   @Column(name = "DISM_DATE")
   public Date getDismountingDate() {
      return dismountingDate;
   }

   public void setDismountingDate(Date mDismountingDate) {
      dismountingDate = mDismountingDate;
   }

   @Column(name = "ACC_START_DATE")
   public Date getAccStartDate() {
      return accStartDate;
   }

   public void setKuStartDate(Date mKuStartDate) {
      kuStartDate = mKuStartDate;
   }

}

FooPK.java 类:

@Embeddable
public class FooPK implements Serializable {

   private static final long serialVersionUID = xxxxxxxxxxxxxxxxxxxL;
   private Long              accId;
   private Long              placeId;
   private Long              installationId;
   private Long              boxId;
   private Integer           fooNumber;
   private Date              dismountingDate;
   private Date              accStartDate;

   @Column(name = "ACC_ID")
   public Long getAccId() {
       return accId;
   }

   public void setAccId(Long mAccId) {
       accId = mAccId;
   }

   @Column(name = "PLACE_ID")
   public Long getPlaceId() {
       return placeId;
   }

   public void setPlaceId(Long mPlaceId) {
       placeId = mPlaceId;
   }

   @Column(name = "INSTALLATION_ID")
   public Long getInstallationId() {
       return installationId;
   }

   public void setInstallationId(Long mInstallationId) {
       installationId = mInstallationId;
   }

   @Column(name = "DISM_DATE")
   public Date getDismountingDate() {
       return dismountingDate;
   }

   public void setDismountingDate(Date mDismountingDate) {
       dismountingDate = mDismountingDate;
   }

   @Column(name = "BOX_ID")
   public Long getBoxId() {
       return boxId;
   }

   public void setBoxId(Long mBoxId) {
       boxId = mBoxId;
   }

   @Column(name = "FOO_ID")
   public Integer getFooNumber() {
       return fooNumber;
   }

   public void setFooNumber(Integer mFooNumber) {
       fooNumber = mFooNumber;
   }

   @Column(name = "ACC_START_DATE")
   public Date getAccStartDate() {
       return accStartDate;
   }

   public void setAccStartDate(Date mAccStartDate) {
       accStartDate = mAccStartDate;
   }

}

感谢您的任何想法!

4

1 回答 1

0

您真的不应该为不唯一的实体定义 ID 。

JPA 是 DB 和 Object 之间的一个非常自以为是的接口,您要么遵循它,要么选择另一种映射/查询技术。

更新、删除、插入具有非唯一 ID 的记录会产生非常不可预测的结果。

如果ACTIVITY_FLAG是您唯一密钥的一部分,只需将其添加到您@ID的 s.

如果您无法将该字段添加为@ID,请添加一个 id 自动递增字段作为表的主键。

如果这两件事都不可能,那么在处理该表时最好使用本机 SQL。

我看到您有一ROW_ID列作为第一列,如果那是您的主键,只需将其设置为您的实体的@ID。

于 2017-04-05T14:16:39.590 回答