比较来自世界各地的卖家的域名和 IT 服务价格

无法获得最后插入的行的标识符 Hibernate 通过 Oracle

我用 Hibernate Tools 3.2.1.GA 使用版本 Spring 3.0.2. 我正在尝试将最后一个插入的字符串的标识符到数据库中获取 Oracle/10g/ 通过以下方式。


Session session=NewHibernateUtil.getSessionFactory//.getCurrentSession//;
session.beginTransaction//;

Country c=new Country//;

c.setCountryId/new BigDecimal/0//;
c.setCountryName/request.getParameter/"txtCountryName"//;
c.setCountryCode/request.getParameter/"txtCountryCode"//;
Zone z=/Zone/ session.get/Zone.class, new BigDecimal/request.getParameter/"zoneId"///;
c.setZone/z/;
session.save/c/;

session.flush//;
System.out.println/c.getCountryId///;
session.getTransaction//.commit//;


预计这次运营商
System.out.println/c.getCountryId///;

将在将数据序列化到数据库中并在修复事务之前返回当前插入的标识符,但由于上一个代码片段中的下一行,这不是那么 /正如我想象的那样/.


c.setCountryId/new BigDecimal/0//;


我不确定为什么在我的案件中需要这种陈述 /插入时/. 我在任何地方都没有看到这句话。 跳过此线导致出现以下异常。

org.hibernate.id.IdentifierGenerationException: 这个类的标识符
必须在拨打之前手动分配 save//: model.Country

这是陈述吗?
c.setCountryId/new BigDecimal/0//;

插入过程中是必需的? 该序列由数据库中的主键生成 Oracle, 而且由于这一行运算符
System.out.println/c.getCountryId///;

总是回报
0

, 实际上必须返回当前会话中的当前插入的标识符。

那么,如何在这种情况下获取最新生成的标识符? 我经历了错误的路径,还有另一种方式吗?

EDIT

:


CREATE TABLE "COUNTRY" 
/
"COUNTRY_ID" NUMBER/35,0/ NOT NULL ENABLE,
"COUNTRY_CODE" VARCHAR2/10/,
"COUNTRY_NAME" VARCHAR2/50/,
"ZONE_ID" NUMBER/35,0/,

CONSTRAINT "COUNTRY_PK" PRIMARY KEY /"COUNTRY_ID"/ ENABLE,
CONSTRAINT "COUNTRY_FK" FOREIGN KEY /"ZONE_ID"/
REFERENCES "ZONE" /"ZONE_ID"/ ON DELETE CASCADE ENABLE
/
/

CREATE OR REPLACE TRIGGER "BI_COUNTRY"
before insert on "COUNTRY"
for each row

begin
select "COUNTRY_SEQ".nextval into :NEW.COUNTRY_ID from dual;
end;

/
ALTER TRIGGER "BI_COUNTRY" ENABLE
/
已邀请:

卫东

赞同来自:

一个例外 "必须在调用之前手动分配此类的标识符。 save//" 意味着您使用标识符生成策略 'Assigned'.

分配

允许应用程序以前为对象分配标识符 save// 叫。 如果未指定项目,这是默认策略。

如果您没有定义任何策略,那么 hibernate 默认为 'assigned'. 'assigned' 该战略意味着 hibernate 它希望应用程序将提供自己的标识符。

如果要使用序列标识符生成器 Oracle, 您可以使用以下配置执行此操作。 -

如果您正在使用 xml -


<id name="countryId" type="java.lang.Integer">
<column name="Country_Id"></column>
<generator class="sequence">
<param name="sequence"/>Country_Id_Seq
</generator>
</id>


如果您使用注释 -


@Id
@GeneratedValue/strategy=GenerationType.SEQUENCE, generator="Country_Id_Seq"/
@SequenceGenerator/name="Country_Id_Seq", sequenceName="Country_Id_Seq" /
private Integer sequence;


你的代码应该看起来像这样 -


Country c=new Country//;

c.setCountryName/request.getParameter/"txtCountryName"//;
c.setCountryCode/request.getParameter/"txtCountryCode"//;
Zone z=/Zone/ session.get/Zone.class, new BigDecimal/request.getParameter/"zoneId"///;
c.setZone/z/;
session.save/c/;

session.flush//;
System.out.println/c.getCountryId///;


执行时 'session.save/c/', hibernate 做出以下挑战 sql 到 Oracle, 提取标识符并将其安装在对象中 Country.


select Country_Id_Seq.nextVal from dual;


触发器问题

当您使用触发器时,在插入字符串时增加标识符时,它将导致草图问题 hibernate. Hibernate 使用序列生成标识符,并且数据库使用触发器来增加标识符。 这导致了标识符加倍。

您有三种解决这个问题的选项。

删除触发器,因为无需。

如果您仍然需要触发器,因为可以在应用程序外更新表,因此只有在指令中未指定时,才会创建标识符以更新触发器 insert
https://coderoad.ru/8002119/

创建一个自定义标识符生成器,​​该生成器使用触发器在将数据中设置数据中的标识符设置到数据库之前。 检查以下链接 -
https://forum.hibernate.org/viewtopic.php?t=973262

小姐请别说爱

赞同来自:

如果列中的值 ID 由序列生成,然后必须将此序列与您的列相关联 ID 在确定本质时,该属性填充了该值 ID 经过 Hibernate 插入过程中。

使用注释

:


@Id
@GeneratedValue/strategy = GenerationType.SEQUENCE, generator = "CountryIdSequence"/
@SequenceGenerator/name = "CountryIdSequence", sequenceName = "COUNTRY_ID_SEQUENCE"/
@Column/name = "COUNTRY_ID"/
private BigDecimal countryId;


使用 hbm

:


<id name="countryId" type="big_decimal">
<column name="COUNTRY_ID"></column>
<generator class="" sequence"="">
<param name="sequence"/>COUNTRY_ID_SEQUENCE
</generator>
</id>


然后,它会在保存后可用。

在数据库级别本质上的任何更改都不会反映在本质层中。 hibernate 直到对象更新。


session.save/c/;
session.flush//;
// Refresh the object for columns modified in the DB by IDENTITY / SEQUENCE / Triggers.
session.refresh/c/;
System.out.println/c.getCountryId///;

要回复问题请先登录注册