GVKun编程网logo

Hibernate:使用增量和Oracle模式的ID生成器(oracle 生成id)

9

这篇文章主要围绕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)

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:生成器

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

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

7.2 Hibernate:内置生成器 – foreign

foreign 生成器使用另一个关联对象的 id,主要用于一对一映射关联。

Hibernate + Oracle 创建自增序列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等相关内容,可以在本站寻找。

本文标签: