7.1 Hibernate:内置生成器 -- assigned

来源:互联网 发布:考勤系统数据读不出 编辑:程序博客网 时间:2024/06/05 20:58

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 class="assigned" />    </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)

修改单元测试代码,添加对ID的赋值:

@Testpublic 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 class="assigned" /> 可以省略,默认生成器策略即为 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@Tablepublic 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")
原创粉丝点击