当前位置: 首页 > 知识库问答 >
问题:

具有空值的JPA复合主键

金珂
2023-03-14

我在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()。

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

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

不幸的是,“主键不能包含null”似乎是最后一句话。我找不到关于这个错误的解决方法的太多信息,这使得看起来似乎没有解决方案。

问题:我想知道是否有人有任何基于Java代码的解决方案,不涉及对数据库进行更改。我目前的解决方法是使用行ID作为表的@ID,但这意味着我不能再使用em.merge()em.find()

以下是我的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\u 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
  ...
}

共有1个答案

卫志泽
2023-03-14

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

客户id是否唯一?如果是这样,那么只需从Id中删除sourceSystem。

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

 类似资料:
  • 我有一个复合主键,其中一个键为空。实体中必须存在哪些注释,以便我可以使用此类JPA获取数据: 我尝试使用IdClass Annotation和EmbeddedId Annotation,但出现异常: 例如,使用了数据,但在实际项目中使用了类似的数据,因此无法用值替换null。

  • 我有一个实体,它的复合主键由两个字段组成,其中一个也是复合外键的一部分。 背景:我有实体<代码>人员 、<代码>区域 和<代码>会话 。 与具有多对多关系,使用称为“和实体。 所以,我有,主键为(,)。本身是的外键。 也有一个字段。我希望(,)是的复合外键。 我的PersonSession代码: } 这看起来不错,它在数据库中创建了所有正确的关系。当我尝试插入个性化会话对象时,问题就出现了——ar

  • 问题内容: 我的JPA模型中有以下类(省略了getters,setters和无关字段): 我需要定义一个类,使得当从所述类生成DDL时,相应的表的主键被由密钥和。我尝试了以下方法: 但这会为表生成以下内容: 请注意,和都是可为空的,当我尝试将DDL加载到SQL Server时会导致以下错误 无法在表“ PRICE”中的可为空的列上定义PRIMARY KEY约束 我不明白为什么这些可以为空,因为在域

  • 当我执行这个查询时,我会得到以下异常

  • 我有一个JPA实体的类层次结构,基类是定义了一个ID的MappedSuperclass。我试图在子类中使用复合键,但这似乎不起作用

  • EmbeddedId或IdClass注释用于表示复合主键。如何在没有(EmbeddedId或IdClass)的情况下使用复合主键? 如果可以在没有(EmbeddedId或IdClass)的情况下使用复合主键,那么如何使用EntityManager.find(Entity Class,Object primaryKey)方法在复合主键(Multiple primaryKey)的情况下查找实体(因为没