用空值JPA复合主键(JPA composite primary key with null val

2019-08-18 03:33发布

我有一个包含在Oracle数据库中的客户数据的表。 下面是一个简单的定义:

CUSTOMER (CUSTOMER_ID NUMBER NOT NULL,
          SOURCE_SYSTEM VARCHAR2(30),
          FULL_NAME VARCHAR2(360),
          PHONE_NUMBER VARCHAR2(240)
          )

此表的主键是(CUSTOMER_ID, SOURCE_SYSTEM)

该表有许多行针对SOURCE_SYSTEM为空。 在数据库级别,没有问题,但是当我尝试访问任何通过JPA实体这些行的,它会导致一些问题:

1:使用em.find()用null来读取行SOURCE_SYSTEM始终会导致正在返回null。

2:使用em.merge()来UPSERT一排空SOURCE_SYSTEM成功,如果记录不存在于表中,但在后续的更新失败,因为合并总是导致插入正在运行。

3:使用em.createQuery()显式地查询与空行导致以下异常:

Exception [EclipseLink-6044] (Eclipse Persistence Services - 2.3.1.v20111018-r10243):
   org.eclipse.persistence.exceptions.QueryException
Exception Description: The primary key read from the row [ArrayRecord(
CUSTOMER.CUSTOMER_ID => 1
CUSTOMER.FULL_NAME => GUY PERSON
CUSTOMER.PHONE_NUMBER => 555-555-1234
CUSTOMER.SOURCE_SYSTEM => null)] during the execution of the query was detected to be null.
   Primary keys must not contain null.
Query: ReadAllQuery(referenceClass=Customer sql="SELECT CUSTOMER_ID, FULL_NAME, PHONE_NUMBER, SOURCE_SYSTEM FROM CUSTOMER WHERE ((CUSTOMER_ID = ?) AND (SOURCE_SYSTEM IS NULL))")

不幸的是,“主键不能包含空”似乎相当决赛。 我无法找到解决方法这个错误,这使得它看起来像没有解决太多的信息。

问题 :我想知道如果任何人有任何Java基于代码的解决方案 ,不涉及更改数据库。 我目前的解决办法是使用ROW_ID@Id的表,但是这意味着我可以不再使用em.merge()em.find()

这里是我的Java类:

Customer.java:

@Entity
@Table(name = "CUSTOMER")
public class Customer implements Serializable {
  private static final long serialVersionUID = 1L;

  @EmbeddedId
  private Customer_Id key;

  @Column(name = "CUSTOMER_ID", nullable = false, insertable = false, updatable = false)
  private Long customerId;
  @Column(name = "SOURCE_SYSTEM", length = 30, insertable = false, updatable = false)
  private String sourceSystem;

  @Column(name = "FULL_NAME", length = 360)
  private String fullName;
  @Column(name = "PHONE_NUMBER", length = 240)
  private String phoneNumber;

  //Setters, Getters, etc
  ...
}

Customer_Id.java

@Embeddable
public class Customer_Id implements Serializable {
  private static final long serialVersionUID = 1L;

  @Column(name = "CUSTOMER_ID", nullable = false)
  private Long customerId;
  @Column(name = "SOURCE_SYSTEM", length = 30)
  private String sourceSystem;

  //Setters, Getters, etc
  ...
}

Answer 1:

主键不能包含空(在JPA或数据库)。 使用不同的值,如“”或“”。

是CUSTOMER_ID独特之处? 如果这样的话只是删除从ID的sourceSystem。

否则,你可以尝试登录的错误有支持空IDS增加。



文章来源: JPA composite primary key with null value