2013-02-02 35 views
1

我有一個類似於下面的2個JPA實體:添加一個新的相關JPA實體試圖插入一排空ID

@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 
} 

我使用的是彈簧數據的JPA產生我DAO層。這是,雖然這不是很有趣:

public interface CustomerRepository extends CrudRepository<Customer, Long> { 
} 

我在Spring上下文調用此並使用@Transactional註解告訴JPA提供程序時的事務提交到數據庫。爲了測試,我使用@PersistenceContext獲取實體管理器並手動刷新它以結束事務。由於我們的應用程序的性質,數據庫中可能存在客戶,但沒有與其關聯的customerInformation對象。如果我在同一個事務中創建一個新客戶和一個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); 
} 

但是,如果我想更新現有的客戶,我碰上它試圖用一個空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. 

我誤解的東西嗎?任何幫助表示讚賞。

在此先感謝!

回答

0

我修改,看起來像這樣的實體:

@Entity 
class CustomerInformation { 

    @Id 
    Long id 

    @MapsId 
    @OneToOne 
    @JoinColumn(name = "id") 
    Customer customer 

    String firstName 
    String lastName 
} 

一切正常。據我所知,CustomerInformation這兩個版本都會導致相同的SQL,除了第二個版本模擬實際的ID,我不一定需要。我會在另一個問題中展開這個,但上面的代碼解決了我的問題。

1

你應該標記Id場也可作爲產生,所以hibernate會來爲它的一些值:

@Entity 
class Customer { 
    @Id 
    @GeneratedValue // !!! 
    Long id 

... 

@Entity 
class CustomerInformation { 
    @Id 
    @GeneratedValue // !!! 
    @OneToOne 
    @JoinColumn(name = "id") 
    Customer customer 

... 
+0

沒有什麼區別。我應該提到'Customer'的Id已經是'@ GeneratedValue',理論上'CustomerInformation'上的註釋應該足以告訴JPA提供者(在我的情況下是Hibernate)它的id應該匹配關聯實體的ID。我錯了嗎?我會更新這個問題,並修正'Customer',但我仍然有同樣的問題。 – Joe

相關問題