2016-01-22 136 views
3

everyone。 我有一個LOG表與觸發器和序列的組合來創建ID,所以當我插入行時,我不必指定ID,否則數據庫會返回錯誤。然而,Hibernate聲稱(正確)是指定的主鍵。帶DB觸發器生成ID的Hibernate映射+序列號

在這種情況下應該使用什麼樣的「發電機」屬性?

我已經嘗試過「分配」它說:

org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned before calling save(): it.m2sc.simulator.beans.Log 

隨着「選擇」 HIB問我自然鍵,但在這個表中沒有自然鍵,但主。

org.hibernate.id.IdentifierGenerationException: no natural-id property defined; need to specify [key] in generator parameters 

這是我的HBM

<hibernate-mapping> 
    <class name="it.m2sc.simulator.beans.Log" table="LOG"> 
     <id name="id" type="integer" column="LOG_ID" access="field"> 
      <generator class="select" /> 
     </id> 
     <property name="date" type="date" column="LOG_DATE" access="field" /> 
     <property name="user" type="string" column="LOG_USER" access="field" /> 
     <property name="evtId" type="integer" column="EVT_ID" access="field" /> 
     <property name="detail" type="string" column="LOG_DETAIL" access="field" /> 
     <property name="deleted" type="character" column="LOG_DELETED" access="field" /> 
     <property name="codiceRaggruppamento" column="LOG_CODICE_RAGGRUPPAMENTO" type="string" access="field" /> 
    </class> 
</hibernate-mapping> 

的Class

public class Log { 
    private Integer id; 
    private Date date; 
    private String user; 
    private Integer evtId; 
    private String detail; 
    private Character deleted = '0'; 
    private String codiceRaggruppamento; 

    ... (getter & setter) 
} 

DDL表/觸發器/序列

CREATE TABLE 
    LOG 
    (
     LOG_ID NUMBER(12) NOT NULL, 
     LOG_DATE TIMESTAMP(6), 
     LOG_USER VARCHAR2(50), 
     EVT_ID NUMBER(12), 
     LOG_DETAIL VARCHAR2(100), 
     LOG_DELETED CHAR(1) DEFAULT '0 ' NOT NULL, 
     LOG_CODICE_RAGGRUPPAMENTO NCHAR(2) NOT NULL, 
     CONSTRAINT LOG_PK PRIMARY KEY (LOG_ID), 
     CONSTRAINT LOG_CFG_EVENT_TYPE_FK1 FOREIGN KEY (EVT_ID) 
     REFERENCES CFG_EVENT_TYPE (EVT_ID) 
    ); 

    CREATE SEQUENCE LOG_SEQ MINVALUE 1 MAXVALUE 999999999999999999999999999 INCREMENT BY 1 START WITH 358 CACHE 20 NOORDER NOCYCLE; 

CREATE OR REPLACE TRIGGER "DTCUSR"."LOG_TRG" BEFORE INSERT ON LOG 
FOR EACH ROW 
BEGIN 
    <<COLUMN_SEQUENCES>> 
    BEGIN 
    IF :NEW.LOG_ID IS NULL THEN 
     SELECT LOG_SEQ.NEXTVAL INTO :NEW.LOG_ID FROM DUAL; 
    END IF; 
    END COLUMN_SEQUENCES; 
END; 

啊,僅供參考:db是ORACLE11

Ty in advice

+0

與嘗試「** **本土」過,它說:「從雙重選擇hibernate_sequence.nextval」 :( –

回答

0

Hibernate doc在不同的生成機制上非常明確。根據數據寫入方式,您應該撥打電話:

對於簡單的使用情況,您可以使用sequence,但還有其他幾個選項可用。

參見:http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/mapping.html#mapping-declaration-id

+0

我讀了參考,因爲它在StackOverflow上的其他主題引用,但不幸的是我還沒有找到我的問題的答案。我寫這篇文章非常詳細,以尋求額外的幫助。 –

0

sequence-identity ID生成策略直接嵌入序列調用INSERT語句:

insert into log (log_id, log_date, log_user, ...) 
values (LOG_SEQ.nextval, ?, ?, ...) 

這種方式,因爲它不需要你可以擺脫觸發的。

此外,您必須將hibernate.jdbc.use_get_generated_keys屬性設置爲true,以便Hibernate在執行插入語句後讀取生成的密鑰。

在的hbm.xml:

<id name="id" type="integer" column="LOG_ID" access="field"> 
    <generator class="sequence-identity" > 
    <param name="sequence">LOG_SEQ</param> 
    </generator> 
</id> 

使用註釋:

@Entity 
@Table(name = "LOG") 
public class Log { 
    @Id 
    @org.hibernate.annotations.GenericGenerator(name="logSequenceGenerator", strategy = "sequence-identity", 
    parameters = {@org.hibernate.annotations.Parameter(name="sequence", value="LOG_SEQ")}) 
    @GeneratedValue(generator = "logSequenceGenerator") 
    @Column(name = "LOG_ID") 
    private Integer id; 
    ... 
} 
+0

問題是我無法擺脫觸發器,這DB是由另一位同事製作的,我必須使用我所擁有的 –

-1

如果要生成僅在數據庫中的ID,並只是讀取休眠您可以使用參數「插入」和@Column註釋中的'updatable':

@Column(name = "LOG_ID", insertable=false, updatable=false) 
private Integer id; 

有了這個參數hibernate不會添加id列來插入和更新。

+0

錯誤。使用@Id這不起作用。我有@Id @Column(name =「ADH_ID」,insertable = false, updatable = false) \t private Long id;''和仍然得到異常:''org.hibernate.id.IdentifierGenerationException:這個類的ids必須手動分配beforeQuery調用save()'' – maxxyme

0

看看這個link解釋如何使用觸發器的發電目標。

Additionaly,記得使用hibernate.jdbc.use_get_generated_keys在財產在Hibernate持久性配置

<property name="hibernate.jdbc.use_get_generated_keys" value="true" /> 

可能在使用環節上所描述的類插入你會得到一個NullPointerException異常。該方法executeAndExtract(PreparedStatement的插入,SessionImplementor會話)更改爲這樣的事

@Override 
    protected Serializable executeAndExtract(PreparedStatement insert, SessionImplementor session) throws SQLException { 

     insert.executeUpdate(); 

     try { 

      ResultSet rs = insert.getGeneratedKeys(); 
      rs.next(); 

      return rs.getLong(1); 

     } catch (RuntimeException rt) { 
      throw new SQLException("Error while attempt to use the CustomTriggerGenerator. Check the <property name=\"hibernate.jdbc.use_get_generated_keys\" value=\"true\" /> in your persistence.xml");  
     } 

    }