2017-06-05 47 views
0

我正在從this book處學習hibernate,我試圖保存一個實體Book。@Id註解不能在Hibernate和Oracle中工作

import javax.persistence.Entity; 



import javax.persistence.Id; 


@Entity 
public class Book { 

@Id 

private int id; 

private String name; 

public String getName() { 
    return name; 
} 

public void setName(String name) { 
    this.name = name; 
} 
} 



    Book book1 = new Book(); 

    book1.setName("Sample"); 
    session.save(book1); 

但此代碼的工作只是一個時間和過多時,有在書籍表中沒有數據,因爲每次它生成「0」作爲主鍵id.Below是異常跟蹤。

ERROR: HHH000346: Error during managed flush 

[org.hibernate.exception.ConstraintViolationException: could not execute statement] 
Exception in thread "main" javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement 
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:147) 
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155) 
    at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162) 
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1403) 
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:473) 
    at org.hibernate.internal.SessionImpl.flushBeforeTransactionCompletion(SessionImpl.java:3133) 
    at org.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2370) 
    at org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access$100(JdbcResourceLocalTransactionCoordinatorImpl.java:38) 
    at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl$TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220) 

Caused by: java.sql.SQLIntegrityConstraintViolationException: ORA-00001: unique constraint (SPRING.SYS_C0015610) violated 

    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:450) 
    at oracle.jdbc.driver.T4CTTIoer.processError(T4CTTIoer.java:399) 
    at oracle.jdbc.driver.T4C8Oall.processError(T4C8Oall.java:1059) 
    at oracle.jdbc.driver.T4CTTIfun.receive(T4CTTIfun.java:522) 
    at oracle.jdbc.driver.T4CTTIfun.doRPC(T4CTTIfun.java:257) 
    at oracle.jdbc.driver.T4C8Oall.doOALL(T4C8Oall.java:587) 
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:225) 
    at oracle.jdbc.driver.T4CPreparedStatement.doOall8(T4CPreparedStatement.java:53) 
    at oracle.jdbc.driver.T4CPreparedStatement.executeForRows(T4CPreparedStatement.java:943) 
    at oracle.jdbc.driver.OracleStatement.doExecuteWithTimeout(OracleStatement.java:1150) 
    at oracle.jdbc.driver.OraclePreparedStatement.executeInternal(OraclePreparedStatement.java:4798) 
    at oracle.jdbc.driver.OraclePreparedStatement.executeUpdate(OraclePreparedStatement.java:4875) 
    at oracle.jdbc.driver.OraclePreparedStatementWrapper.executeUpdate(OraclePreparedStatementWrapper.java:1361) 
    at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:204) 
    ... 19 more 

書上說:

默認情況下,@Id註釋會自動確定最合適的主 鍵生成策略使用,則可以通過還應用@GeneratedValue 註釋

覆蓋此

但是,如果我使用帶有@ID的@GeneratedValue註釋,則代碼可以正常工作,並且每次都會生成一個新的主鍵ID。這種情況對我來說沒有意義。我錯過了什麼或者是否有任何數據庫特定問題?

CREATE TABLE BOOK(
ID INTEGER, 
NAME VARCHAR2(50) 
); 

ALTER TABLE BOOK ADD PRIMARY KEY(ID); 

回答

1

使用Hibernate 分配默認生成策略,如果沒有的元素。在這種情況下,您的應用程序會分配實體的ID。 如果你想休眠會照顧自動生成的ID,那麼你應該使用GeneratedValue或任何其它ID生成策略

@Id 
@GeneratedValue(strategy = GenerationType.AUTO) 

here是一些例子

您的ID類型爲int

private int id; 

當你第一次插入值,然後jvm將分配id默認值0,所以休眠很容易插入id值爲0, 現在,當你再次嘗試插入值,因爲沒有身份證生成器策略然後再次jvm設置id默認值0,當hibernate嘗試插入它與ID 0值然後其拋出ConstraintViolationException異常,因爲ID已存在數據庫中的值爲0。 所以,如果你想與自動休眠分配ID爲你的實體,您可以使用JPA特定@GeneratedValue策略(AUTO/IDENTITY /順序/ TABLE) 或會照顧給ID爲實體

 increment 
     sequence 
     hilo 
     native 
     identity 
     seqhilo 
     uuid 
     guid 
     select 
     foreign 
     sequence-identity 
另一休眠策略
+0

Bhushan那麼這是什麼意思? 「默認情況下,Id註釋會自動確定要使用的最合適的主鍵生成策略 - 您也可以通過應用GeneratedValue註釋來覆蓋此註釋。」每次都需要重寫策略嗎? – Steve

+0

@Steve作爲我剛纔提到的,當你剛剛使用'@ Id'然後分配策略使用意味着你將負責爲你的實體分配id而不是休眠。 你也可以簡單介紹一下我什麼意思是'我需要每次重寫策略?' –

+0

就像本書默認所說'@Id'註釋將處理使用的主鍵生成策略。如果想改變默認策略,可以使用'@GeneratedValue'。所以我的問題是爲什麼不是'@Id'爲我處理策略。爲什麼它使用int變量的默認值。 – Steve