大家。 我有一个带有触发器和序列组合的LOG表来创建id,所以当我插入行时,我不必指定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>
班级
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;
啊,只是fyi:db是Oracle11
Ty in advice
答案 0 :(得分: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在执行insert语句后读取生成的键。
在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;
...
}
答案 1 :(得分:0)
看看这个link解释如何使用基于触发器的生成器。
另外,请记住在Hibernate持久性配置中使用hibernate.jdbc.use_get_generated_keys属性
<property name="hibernate.jdbc.use_get_generated_keys" value="true" />
使用链接中描述的类插入时,可能会出现NullPointerException。将方法executeAndExtract(PreparedStatement insert,SessionImplementor session)更改为此类
@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");
}
}
答案 2 :(得分:-1)
Hibernate doc对于可用的不同生成机制非常清楚。根据数据的编写方式,应拨打电话:
对于简单的用例,您可以使用sequence
,但还有其他几个选项。
参考:http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/mapping.html#mapping-declaration-id
答案 3 :(得分:-1)
如果您希望您的ID仅在数据库中生成并且只是通过hibernate读取,您可以在@Column注释中使用参数'insertable'和'updatable':
@Column(name = "LOG_ID", insertable=false, updatable=false)
private Integer id;
使用此参数,hibernate不会将id列添加到插入和更新中。
答案 4 :(得分:-1)
要实现目标,您需要使用GenerationType.IDENTITY
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "LOG_ID", updatable = false, nullable = false)
private Integer id;
详情请见https://www.thoughts-on-java.org/jpa-generate-primary-keys/