У меня есть таблица, содержащая данные клиента в базе данных оракула. Вот упрощенное определение:
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 Entity, это вызывает ряд проблем:
1: Использование em.find()
для извлечения строки с нулем SOURCE_SYSTEM
всегда приводит к возврату null.
2: Использование em.merge()
для повышения строки с нулевым SOURCE_SYSTEM
завершается успешно, если запись не существует в таблице, но сбой при последующих обновлениях, потому что слияние ALWAYS приводит к запуску вставки.
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
...
}