次のような 2 つの JPA エンティティがあります。
@Entity
class Customer {
@Id
@GeneratedValue
Long id
@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn
CustomerInformation customerInformation
}
@Entity
class CustomerInformation {
@Id
@OneToOne
@JoinColumn(name = "id")
Customer customer
String firstName
String lastName
}
spring-data-jpa を使用して DAO レイヤーを生成しています。これはあまり興味深いものではありませんが、次のとおりです。
public interface CustomerRepository extends CrudRepository<Customer, Long> {
}
これを春のコンテキストで呼び出し、 @Transactional アノテーションを使用して、いつトランザクションをデータベースにコミットするかを JPA プロバイダーに伝えます。テストのために、@PersistenceContext を使用してエンティティ マネージャーを取得し、手動でフラッシュしてトランザクションを終了します。アプリケーションの性質上、customerInformation オブジェクトが関連付けられていない Customer がデータベースに存在する場合があります。同じトランザクションで新しい顧客と customerInformation オブジェクトを作成すると、期待どおりに機能します。たとえば、これは機能します:
@Transactional
public void createNewCustomer() {
Customer cust = new Customer();
CustomerInformation custInf = new CustomerInformation;
custInf.setCustomer(cust);
custInf.setFirstName("asdf");
custInf.setLastName("hjkl");
cust.setCustomerInformation(custInf);
customerRepository.save(cust);
}
しかし、既存の顧客を更新したい場合、null ID を持つ CustomerInformation オブジェクトを挿入しようとする問題に遭遇します。たとえば、これは惨めに失敗します。
@Transactional
public void updateExistingCustomer(Long userId) {
Customer foundCustomer = customerRepository.findOne(userId);
if (foundCustomer.getCustomerInformation() == null) {
CustomerInformation custInf = new CustomerInformation();
custInf.setCustomer(foundCustomer);
custInf.setFirstName("asdf");
custInf.setLastName("hjkl");
cust.setCustomerInformation(custInf);
customerRepository.save(foundCustomer);
}
}
これは次のエラー メッセージで失敗します。
Hibernate: insert into CustomerInformation (firstName, lastName, id) values (?, ?, ?)
Feb 1, 2013 7:40:12 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 20000, SQLState: 23502
Feb 1, 2013 7:40:12 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Column 'ID' cannot accept a NULL value.
私は何か誤解していますか?どんな助けでも大歓迎です。
前もって感謝します!