具有空值的JPA复合主键

我有一个包含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为null。 在数据库级别,没有问题,但是当我尝试通过JPA实体访问任何这些行时,它会导致许多问题:

1:使用em.find()获取具有空SOURCE_SYSTEM的行总是会返回null。

2:如果表中不存在记录,则使用em.merge()来插入具有空SOURCE_SYSTEM的行成功,但在后续更新时失败,因为合并ALWAYS会导致运行插入。

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

 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))") 

不幸的是,“主键不能包含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 ... } 

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

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

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