这篇文章主要围绕Hibernate:使用增量和Oracle模式的ID生成器和oracle生成id展开,旨在为您提供一份详细的参考资料。我们将全面介绍Hibernate:使用增量和Oracle模式的ID
这篇文章主要围绕Hibernate:使用增量和Oracle模式的ID生成器和oracle 生成id展开,旨在为您提供一份详细的参考资料。我们将全面介绍Hibernate:使用增量和Oracle模式的ID生成器的优缺点,解答oracle 生成id的相关问题,同时也会为您带来7 Hibernate:生成器、7.1 Hibernate:内置生成器 – assigned、7.2 Hibernate:内置生成器 – foreign、Hibernate + Oracle 创建自增序列ID的实用方法。
本文目录一览:- Hibernate:使用增量和Oracle模式的ID生成器(oracle 生成id)
- 7 Hibernate:生成器
- 7.1 Hibernate:内置生成器 – assigned
- 7.2 Hibernate:内置生成器 – foreign
- Hibernate + Oracle 创建自增序列ID
Hibernate:使用增量和Oracle模式的ID生成器(oracle 生成id)
我正在使用Hiberbnate 3.1.3。我有如下映射,当我尝试将记录插入TEST_TABLE时,出现异常:’线程“ main”
org.hibernate.exception.SQLGrammarException中的异常:无法获取增量生成器的初始值”
<class name="com.test.app.to.TestTable" table="TEST_TABLE" schema="TEST"> <id name="testId" type="long"> <column name="TEST_ID" precision="12" scale="0" /> <generator></generator> </id></class>
我在cfg.xml中设置了以下默认模式,因为我需要在应用程序中使用OTHER_SCHEMA中的表。
<property name="hibernate.default_schema">OTHER_SCHEMA</property>
在上述情况下,这似乎是一个Hibernate Bug,因为使用TestTable对象进行读取可以正常工作并正确使用“
TEST”模式,但是''<generator></generator>''
不使用“ TEST”模式,而是使用默认的“
OTHER_SCHEMA”来获取最大值ID。为最大ID生成的查询如下:
Hibernate: select max(TEST_ID) from OTHER_SCHEMA.TEST_TABLE
我无法为生成器指定架构,并且未使用我希望其使用的类的schema =“ TEST”属性。
该问题如何解决?
答案1
小编典典您 可以 使用 schema 参数为生成器指定架构:
<generator> <param name="schema">TEST</param></generator>
可悲的是,这在Hibernate文档中没有很好地描述。您必须查看API
javadoc才能找到答案。
也就是说,Mark关于“增量”效率不是很高是正确的-在集群环境中它也不安全。
7 Hibernate:生成器
Hibernate 定义了许多生成器类用于生成持久化类对象的唯一标识符。
所有生成器类都实现了 org.hibernate.id.IdentifierGenerator
接口,可以通过自定义该接口实现来创建新的生成器。
Hibernate 内置的生成器包括:
- assigned
- foreign
- guid
- hilo
- identity
- increment
- native
- select
- seqhilo
- sequence
- uuid
- org.hibernate.envers.enhanced.OrderedSequenceGenerator
本系列所有示例代码的 Hibernate 配置文件参看:
2 Hibernate:入门简介
4 Hibernate:使用注解(Annotation)
部分示例代码需要将配置文件中数据库连接池数加大。
7.1 Hibernate:内置生成器 – assigned
assigned
是 Hibernate 内置的默认生成器策略,应用程序应该对持久化对象的唯一标识符赋值。
特点:可以跨数据库,人为控制主键生成,建议尽量避免。
1 使用 XML
1.1 持久化类定义:
package hibernate;
import java.util.Date;
public class Person {
private Integer id;
private String account;
private String name;
private Date birth;
public Person() {}
public Person(String account, String name, Date birth) {
this.account = account;
this.name = name;
this.birth = birth;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Person [id=" + id + ", account=" + account + ", name=" + name + ", birth=" + birth + "]";
}
}
1.2 定义映射:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="hibernate.Person" table="PERSON">
<id name="id" type="int">
<column name="ID" />
<generator/>
</id>
<property name="account" type="java.lang.String">
<column name="ACCOUNT" />
</property>
<property name="name" type="java.lang.String">
<column name="NAME" />
</property>
<property name="birth" type="java.util.Date">
<column name="BIRTH" />
</property>
</class>
</hibernate-mapping>
1.3 单元测试:
package hibernate;
import java.util.Date;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.Configuration;
import org.junit.Test;
public class HibernateTest {
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Person person = new Person("admin", "Nick", new Date(System.currentTimeMillis()));
session.save(person);
transaction.commit();
session.close();
sessionFactory.close();
}
}
单元测试抛出异常 org.hibernate.id.IdentifierGenerationException,提示保存前必须为此类的唯一标识赋值。
org.hibernate.id.IdentifierGenerationException: ids for this class must be manually assigned beforeQuery calling save(): hibernate.Person
at org.hibernate.id.Assigned.generate(Assigned.java:33)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:105)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:192)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:38)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:177)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:32)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:73)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:689)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:681)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:676)
at hibernate.HibernateTest.test(HibernateTest.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:86)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:678)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)
1.4 修改单元测试代码,添加对ID的赋值:
@Test
public void test() {
Configuration configuration = new Configuration().configure("hibernate.cfg.xml");
SessionFactory sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
Person person = new Person("admin", "Nick", new Date(System.currentTimeMillis()));
person.setId(999);
session.save(person);
transaction.commit();
session.close();
sessionFactory.close();
}
保存后运行,测试通过,数据库中已经查询到新增数据(测试结果略) 。
注意:
- 持久化类定义唯一标识属性的类型设为
java.lang.Integer
,不能设置为原始类型int
,否则第一次运行单元测试即通过,因为int
默认初始值为0
,而java.lang.Integer
必须手动赋值,否则为null
。 - XML 映射文件中
<generator/>
可以省略,默认生成器策略即为assigned
。
2 使用注解(annotation)
使用注解定义持久化类:
package hibernate;
import java.util.Date;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;
import org.hibernate.annotations.GenericGenerator;
@Entity
@Table
public class Person {
@Id
@GeneratedValue(generator = "assignedGenerator")
@GenericGenerator(name = "assignedGenerator", strategy = "assigned")
private Integer id;
private String account;
private String name;
private Date birth;
public Person() {}
public Person(String account, String name, Date birth) {
this.account = account;
this.name = name;
this.birth = birth;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getAccount() {
return account;
}
public void setAccount(String account) {
this.account = account;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirth() {
return birth;
}
public void setBirth(Date birth) {
this.birth = birth;
}
@Override
public String toString() {
return "Person [id=" + id + ", account=" + account + ", name=" + name + ", birth=" + birth + "]";
}
}
运行【1.3 单元测试】,测试结果相同。
以下注解可以省略:
@GeneratedValue(generator = "assignedGenerator")
@GenericGenerator(name = "assignedGenerator", strategy = "assigned")
7.2 Hibernate:内置生成器 – foreign
foreign
生成器使用另一个关联对象的 id,主要用于一对一映射关联。
Hibernate + Oracle 创建自增序列ID
1.创建自增序列
2.对ID创建触发器
3.Userinfo.hbm.xml使得<generator>
序列:
CREATE SEQUENCE "SYSTEM"."SEQUENCE_ID" MINVALUE 1 MAXVALUE 99999999999 INCREMENT BY 1 START WITH 61 CACHE 20 ORDER NOCYCLE ;
触发器:
create or replace trigger TRIG_USERINFO
before insert on "USERINFO"
for each row
begin
select SEQUENCE_ID.nextval into :NEW."ID" from dual;
end;
Userinfo.hbm.xml:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<!--
Mapping file autogenerated by MyEclipse Persistence Tools
-->
<hibernate-mapping>
<class name="org.bean.Userinfo" table="USERINFO" schema="SYSTEM">
<id name="id" type="java.lang.Integer">
<column name="ID" precision="9" scale="0" />
<generator class="increment">
</generator>
</id>
<property name="username" type="java.lang.String">
<column name="USERNAME" length="50" />
</property>
<property name="password" type="java.lang.String">
<column name="PASSWORD" length="50" />
</property>
</class>
</hibernate-mapping>
DAO:
package org.dao;
import java.util.List;
import org.bean.Userinfo;
import org.hibernate.Query;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.util.HibernateSessionFactory;
public class UserDAO {
public Session session;
//获得session方法
public void getCurrentSession(){
//调用HibernateSessionFactory的getSession方法创建Session对象
session = HibernateSessionFactory.getSession();
}
//关闭sesson方法
public void closeSession(){
if(session != null){
HibernateSessionFactory.closeSession();
}
}
//插入一条记录方法
public void save(String username,String password) {
Transaction t1 = session.beginTransaction();
Userinfo userinfo = new Userinfo();
userinfo.setUsername(username);
userinfo.setPassword(password);
session.save(userinfo);
t1.commit();
}
//修改这条方法
public void update(int id, String username){
Transaction t2 = session.beginTransaction();
Userinfo userinfo = (Userinfo) session.get(Userinfo.class, id);
userinfo.setUsername(username);
session.update(userinfo);
t2.commit();
}
//查询数据库结果方法
public void queryAllUser(){
try{
Query query = session.createQuery("from Userinfo");
List list = query.list();
for (int i = 0; i < list.size(); i++) {
Userinfo user = (Userinfo)list.get(i);
System.out.println(user.getId() + " " + user.getUsername());
}
}catch (Exception e) {
e.printStackTrace();
}
}
//删除该条记录方法
public void deleteUser(int id) {
Transaction t3 = session.beginTransaction();
Userinfo userinfo = (Userinfo) session.get(Userinfo.class, id);
session.delete(userinfo);
t3.commit();
}
}
Userinfo.java:
package org.bean;
/**
* Userinfo entity. @author MyEclipse Persistence Tools
*/
public class Userinfo implements java.io.Serializable {
// Fields
private Integer id;
private String username;
private String password;
// Constructors
/** default constructor */
public Userinfo() {
}
/** full constructor */
public Userinfo(String username, String password) {
this.username = username;
this.password = password;
}
// Property accessors
public Integer getId() {
return this.id;
}
public void setId(Integer id) {
this.id = id;
}
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
}
关于Hibernate:使用增量和Oracle模式的ID生成器和oracle 生成id的问题我们已经讲解完毕,感谢您的阅读,如果还想了解更多关于7 Hibernate:生成器、7.1 Hibernate:内置生成器 – assigned、7.2 Hibernate:内置生成器 – foreign、Hibernate + Oracle 创建自增序列ID等相关内容,可以在本站寻找。
本文标签: