具有空值的JPA复合主键

Mat*_* Q. 12 java jpa eclipselink ejb-3.0 jpa-2.0

我有一个包含oracle数据库中客户数据的表.这是一个简化的定义:

CUSTOMER (CUSTOMER_ID NUMBER NOT NULL,
          SOURCE_SYSTEM VARCHAR2(30),
          FULL_NAME VARCHAR2(360),
          PHONE_NUMBER VARCHAR2(240)
          )
Run Code Online (Sandbox Code Playgroud)

该表的主键是(CUSTOMER_ID, SOURCE_SYSTEM).

该表有许多行为SOURCE_SYSTEMnull.在数据库级别,没有问题,但是当我尝试通过JPA实体访问任何这些行时,它会导致许多问题:

1:em.find()用于获取具有null的行SOURCE_SYSTEM总是导致返回null.

2:如果表中不存在记录,则使用em.merge()以空值SOURCE_SYSTEM成功的行成功,但在后续更新时失败,因为合并始终导致正在运行插入.

3:使用em.createQuery()显式查询具有null的行会导致以下异常:

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))")
Run Code Online (Sandbox Code Playgroud)

不幸的是,"主键不能包含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
  ...
}
Run Code Online (Sandbox Code Playgroud)

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
  ...
}
Run Code Online (Sandbox Code Playgroud)

Jam*_*mes 1

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

customer_id 是否唯一?如果是这样,那么只需从 Id 中删除 sourceSystem 即可。

否则,您可以尝试记录错误以添加对空 ID 的支持。