- 浏览: 364555 次
- 来自: 北京
文章分类
- 全部博客 (237)
- XML (6)
- JavaSE (39)
- Junit (1)
- Maven (10)
- JavaScript (12)
- JavaEE (16)
- HTML5 (10)
- java多线程 (8)
- Hibernate (30)
- Java反射 (3)
- Spring (11)
- Struts (1)
- svn (2)
- linux (12)
- 代码实例 (1)
- 设计模式 (1)
- UML (1)
- javassist (1)
- Oracle (3)
- Hibernate异常 (9)
- DWR (6)
- Java泛型 (2)
- SpringMVC (11)
- Dbunit (3)
- github (2)
- Algorithm (1)
- zTree (1)
- jquery (7)
- freemarker (4)
- mysql (5)
- ffmpeg (1)
- 编码 (1)
- lucene (15)
- hadoop (1)
- JVM (1)
- Regular Expressions (5)
- myeclipse (1)
- 爬虫 (7)
- 加密 (3)
- WebService (2)
- Socket (2)
- Windows (1)
最新评论
-
wxpsjm:
好直接
HV000030: No validator could be found for type: java.lang.Integer. -
wxhhbdx:
学习了,对新手来说很不错的教程。
SpringMVC入门 (二) 数值传递 -
xgcai:
正好在学dwr
DWR入门 (二)用户实例
这篇是关于如何配置Hibernate实现复合主键的映射功能。
摘自圣思园Hibernate.25的后半部分和26的前半部分。
1.要使用复合主键,对应类Student必须实现Serializable接口。
2.要重写hashCode和equals方法。
重写hashCode和equals方法的原因:
Hibernate要判断两个对象是否相同,避免出现两个复合主键相同的对象实例被加入数据库(数据库也不会接收)。
因此Hibernate会通过hashCode和equals方法来判断是否可以将两个对象放入诸如Set这样的集合中去。
Student.java
Student.hbm.xml
运行configure(),会产生以下SQL语句。
create table test_student(
card_id varchar2(255) not null,
name varchar2(255) not null,
age number(10),
primary key(card_id,name));
插入
运行以下插入代码,便会报错了。
Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [composite.Student#composite.Student@abc1a76f]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:179)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:135)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:764)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:756)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:752)
at composite.Hibernate_1Insert.main(Hibernate_1Insert.java:27)
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
即是说,这个identifier值已经被session存储了,并且指向已经存在的对象。而再存入另一个对象,也就是s2的时候,又提取出来了同样的identifier。
查询
随便瞎写一个查询语句:
这里的报错信息是:
org.hibernate.TypeMismatchException: Provided id of the wrong type for class composite.Student. Expected: class composite.Student, got class java.lang.String
提供id类型不正确,期待的是composite.Student类型,而不是java.lang.String.
为什么Student要实现Serializable接口?
在使用get或load方法的时候需要先构建出来该实体类的对象,并且将查询依据(联合主键)设置进去,然后作为get或者load方法的第二个参数传进去即可。
用过Hibernate的就知道,Hibernate的get和load方法接受的都是一个Class和一个Serializable类型对象。
Hibernate API文档:
Object org.hibernate.Session.get(Class clazz, Serializable id)
Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance. (If the instance is already associated with the session, return that instance. This method never returns an uninitialized instance.)
因此在Student实现了Serializable接口之后,我们就可以通过如下的查询方式:
摘自圣思园Hibernate.25的后半部分和26的前半部分。
1.要使用复合主键,对应类Student必须实现Serializable接口。
2.要重写hashCode和equals方法。
重写hashCode和equals方法的原因:
Hibernate要判断两个对象是否相同,避免出现两个复合主键相同的对象实例被加入数据库(数据库也不会接收)。
因此Hibernate会通过hashCode和equals方法来判断是否可以将两个对象放入诸如Set这样的集合中去。
Student.java
package composite; import java.io.Serializable; public class Student implements Serializable { //这里用name和cardId作为联合主键 private String cardId; private String name; private int age; @Override public int hashCode() { final int prime = 31; int result = 1; result = prime * result + ((cardId == null) ? 0 : cardId.hashCode()); result = prime * result + ((name == null) ? 0 : name.hashCode()); return result; } @Override public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (getClass() != obj.getClass()) return false; Student other = (Student) obj; if (cardId == null) { if (other.cardId != null) return false; } else if (!cardId.equals(other.cardId)) return false; if (name == null) { if (other.name != null) return false; } else if (!name.equals(other.name)) return false; return true; } }
Student.hbm.xml
<hibernate-mapping package="composite"> <class name="Student" table="test_student"> <!-- composite-id表示复合主键 --> <composite-id> <!-- key-property表示组成主键的元素 --> <key-property name="cardId" column="card_id" type="string"/> <key-property name="name" column="name" type="string"/> </composite-id> <property name="age" column="age" type="int"/> </class> </hibernate-mapping>
运行configure(),会产生以下SQL语句。
create table test_student(
card_id varchar2(255) not null,
name varchar2(255) not null,
age number(10),
primary key(card_id,name));
插入
运行以下插入代码,便会报错了。
Session session=HibernateUtil.openSession(); Transaction tx=session.beginTransaction(); Student s1=new Student("111", "alleni", 22); Student s2=new Student("111","alleni",22); session.save(s1); session.save(s2); tx.commit();
Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session: [composite.Student#composite.Student@abc1a76f]
at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:179)
at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:135)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.saveWithGeneratedOrRequestedId(DefaultSaveOrUpdateEventListener.java:206)
at org.hibernate.event.internal.DefaultSaveEventListener.saveWithGeneratedOrRequestedId(DefaultSaveEventListener.java:55)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:191)
at org.hibernate.event.internal.DefaultSaveEventListener.performSaveOrUpdate(DefaultSaveEventListener.java:49)
at org.hibernate.event.internal.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:90)
at org.hibernate.internal.SessionImpl.fireSave(SessionImpl.java:764)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:756)
at org.hibernate.internal.SessionImpl.save(SessionImpl.java:752)
at composite.Hibernate_1Insert.main(Hibernate_1Insert.java:27)
org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
即是说,这个identifier值已经被session存储了,并且指向已经存在的对象。而再存入另一个对象,也就是s2的时候,又提取出来了同样的identifier。
查询
随便瞎写一个查询语句:
Student s=(Student) session.get(Student.class,"111"); System.out.println(s.getName());
这里的报错信息是:
org.hibernate.TypeMismatchException: Provided id of the wrong type for class composite.Student. Expected: class composite.Student, got class java.lang.String
提供id类型不正确,期待的是composite.Student类型,而不是java.lang.String.
为什么Student要实现Serializable接口?
在使用get或load方法的时候需要先构建出来该实体类的对象,并且将查询依据(联合主键)设置进去,然后作为get或者load方法的第二个参数传进去即可。
用过Hibernate的就知道,Hibernate的get和load方法接受的都是一个Class和一个Serializable类型对象。
Hibernate API文档:
Object org.hibernate.Session.get(Class clazz, Serializable id)
Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance. (If the instance is already associated with the session, return that instance. This method never returns an uninitialized instance.)
因此在Student实现了Serializable接口之后,我们就可以通过如下的查询方式:
Session session=HibernateUtil.openSession(); //先构建出来查询的依据,一个Student对象。 Student student_primaryKey=new Student(); student_primaryKey.setCardId("111"); student_primaryKey.setName("alleni"); Student s=(Student) session.get(Student.class,student_primaryKey); System.out.println(s.getName()); System.out.println(s.getAge());
发表评论
-
Connection is read-only. Queries leading to data modification are not allowed。
2014-04-06 21:52 3648<tx:advice id="txAdvic ... -
org.hibernate.HibernateException: No Session found for current thread
2014-04-06 12:37 0今天在maven中整合spring和hibernate,并使用 ... -
select new Topic from ' Mysql 生成SQL语句错误
2014-03-30 22:51 1616Caused by: com.mysql.jdbc.exce ... -
Unable to locate appropriate constructor on class
2014-02-20 00:11 1420org.hibernate.hql.internal.ast. ... -
Hibernate的load和get实际应用区分简单实例
2013-12-18 11:58 829今天在看孔浩的CMS视频时候看到的。 在57 -文章管理06 ... -
自定义OpenSessionInViewer过滤器
2013-12-11 12:12 995摘自孔浩视频 spring部分-17_spring_SSH整合 ... -
数据库事务 (三)虚读(Phantom Read)
2013-12-01 13:21 0关于各种读 虚读 phantom read: 转自维基 ... -
Hibernate悲观锁
2013-11-30 17:30 0为了防止两个线程同时修改一个数据,造成更新数据丢失,我们可以使 ... -
Hibernate查询HQL实例
2013-11-29 15:56 1251三个实体类对象: public class Team { ... -
QBC与HQL检索
2013-11-28 17:39 0QBC(Query By Criteria) API提供了检索 ... -
Hibernate继承映射
2013-11-28 12:36 611继承映射分为三种情况 1.每个子类一张表 比如说有一个Pers ... -
Hibernate通过Composite-element配置外联表实例 (码)
2013-11-28 11:07 982摘自圣思园Hibenrate 26. 组件映射深度解析 -37 ... -
Hibernate配置复合主键 composite primary key (二)
2013-11-27 16:41 1404摘自圣思园Hibernate 26.组件映射深度解析 上一篇 ... -
Hibernate通过Comparator接口自定义排序规则
2013-11-25 20:42 2470摘自圣思园 Hibernate25.自定义内存排序器详解及符合 ... -
Hibernate配置Set和List
2013-11-25 10:44 1838========================Set==== ... -
Hibernate的Map配置
2013-11-23 16:21 1257摘自圣思园022.Hibernate映 ... -
Hibernate多对多配置
2013-11-21 22:39 841场景: Student和Course,每一个Student有多 ... -
Hibernate延迟加载案例 (多: 一: 一,附代码)
2013-11-21 17:41 557摘自圣思园Hibernate20.一 ... -
Hibernate一对一配置
2013-11-20 21:49 997摘自圣思园 19.Hibernate的对象检索策略深度解析.a ... -
Hibernate的对象检索策略 (一) SQL左外连接检索策略
2013-11-20 15:32 1093首先是测试表的结构: 先通过hibernate将数据放入 ...
相关推荐
触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (可选) 5.1.9. property 5.1.10. 多对...
触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (可选) 5.1.9. property 5.1.10. 多对一...
触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (optional) 5.1.9. property 5.1.10. 多对一...
触发器实现的主键生成器(Primary keys assigned by triggers) 6.1.5. composite-id 6.1.6. 鉴别器(discriminator) 6.1.7. 版本(version)(可选) 6.1.8. timestamp (optional) 6.1.9. property 6.1.10. 多...
触发器实现的主键生成器(Primary keys assigned by triggers) 6.1.5. composite-id 6.1.6. 鉴别器(discriminator) 6.1.7. 版本(version)(可选) 6.1.8. timestamp (optional) 6.1.9. property 6.1.10. 多...
触发器实现的主键生成器(Primary keys assigned by triggers) 6.1.5. composite-id 6.1.6. 鉴别器(discriminator) 6.1.7. 版本(version)(可选) 6.1.8. timestamp (optional) 6.1.9. property 6.1.10. ...
触发器实现的主键生成器(Primary keys assigned by triggers) 6.1.5. composite-id 6.1.6. 鉴别器(discriminator) 6.1.7. 版本(version)(可选) 6.1.8. timestamp (optional) 6.1.9. property 6.1.10. ...
触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (optional) 5.1.9. property 5.1.10. 多对一...
触发器实现的主键生成器(Primary keys assigned by triggers) 5.1.5. composite-id 5.1.6. 鉴别器(discriminator) 5.1.7. 版本(version)(可选) 5.1.8. timestamp (可选) 5.1.9. property 5.1.10. 多对一...
Table of Contents Preface 1. Introduction to Hibernate ... Many-to-many with shared composite key attribute 23.4.4. Content based discrimination 23.4.5. Associations on alternate keys 24. Best Practices
Spring Boot和JPA的Hibernate教程和演示