- 浏览: 375775 次
- 来自: 北京
文章分类
- 全部博客 (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 3720<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 1651Caused by: com.mysql.jdbc.exce ... -
Unable to locate appropriate constructor on class
2014-02-20 00:11 1460org.hibernate.hql.internal.ast. ... -
Hibernate的load和get实际应用区分简单实例
2013-12-18 11:58 871今天在看孔浩的CMS视频时候看到的。 在57 -文章管理06 ... -
自定义OpenSessionInViewer过滤器
2013-12-11 12:12 1054摘自孔浩视频 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 1291三个实体类对象: public class Team { ... -
QBC与HQL检索
2013-11-28 17:39 0QBC(Query By Criteria) API提供了检索 ... -
Hibernate继承映射
2013-11-28 12:36 645继承映射分为三种情况 1.每个子类一张表 比如说有一个Pers ... -
Hibernate通过Composite-element配置外联表实例 (码)
2013-11-28 11:07 1014摘自圣思园Hibenrate 26. 组件映射深度解析 -37 ... -
Hibernate配置复合主键 composite primary key (二)
2013-11-27 16:41 1446摘自圣思园Hibernate 26.组件映射深度解析 上一篇 ... -
Hibernate通过Comparator接口自定义排序规则
2013-11-25 20:42 2514摘自圣思园 Hibernate25.自定义内存排序器详解及符合 ... -
Hibernate配置Set和List
2013-11-25 10:44 1877========================Set==== ... -
Hibernate的Map配置
2013-11-23 16:21 1295摘自圣思园022.Hibernate映 ... -
Hibernate多对多配置
2013-11-21 22:39 875场景: Student和Course,每一个Student有多 ... -
Hibernate延迟加载案例 (多: 一: 一,附代码)
2013-11-21 17:41 589摘自圣思园Hibernate20.一 ... -
Hibernate一对一配置
2013-11-20 21:49 1037摘自圣思园 19.Hibernate的对象检索策略深度解析.a ... -
Hibernate的对象检索策略 (一) SQL左外连接检索策略
2013-11-20 15:32 1136首先是测试表的结构: 先通过hibernate将数据放入 ...
相关推荐
这种情况通常出现在那些通过多个字段共同唯一标识一条记录的复合主键(Composite Key)场景。本文将详细介绍如何在Hibernate中进行无主键表映射,并结合提供的资源进行说明。 首先,我们要理解什么是复合主键。在...
联合主键(Composite Primary Key),是指在数据库表中使用两个或多个字段共同作为主键来唯一标识每一行记录。这种方式在实际应用中非常常见,尤其是在需要通过多维度数据来确定唯一性的场景下。 ### Hibernate联合...
6. **Composite Primary Key**:复合主键,用于标识表中的记录,当单一字段不足以唯一标识一条记录时使用。 **SessionFactory的作用**: - **创建Session实例**:SessionFactory负责创建Session实例,并管理这些...
触发器实现的主键生成器(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. 多对...
**联合主键(Composite Primary Key)**在JPA中,当一个实体的主键由两个或更多个字段组成时,我们称之为联合主键。`JPACompositePK`示例将说明如何使用`@Embeddable`和`@EmbeddedId`注解来定义这样的主键。 在这些...
触发器实现的主键生成器(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. 多...
4. **复合主键(Composite Primary Keys)**: 当一个实体的主键由两个或更多字段组成时,可以使用`@IdClass`或`@EmbeddedId`注解来定义复合主键。 5. **双向关联(Bidirectional Relationships)**: 在两个实体之间...
**六、复合主键(Composite Primary Key)** 当一个实体的主键由两个或更多个属性组成时,可以使用@EmbeddedId和@Embeddable注解定义复合主键。 **七、Element Collection** Element Collection用于将非实体类型的...
触发器实现的主键生成器(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. 多...
复合主键(Composite Primary Key) 复合主键是指使用多个属性变量(表中的多列)联合起来作为主键。为了实现复合主键,需要编写一个复合主键类(CompositePrimaryKeyClass),并遵循以下规则: - **复合主键类...
复合主键 (Composite Primary Key) - **定义**:当需要使用多个属性变量(表中的多列)联合起来作为主键时,就需要使用复合主键。复合主键要求开发者自定义一个复合主键类。 - **示例**: ```java @Embeddable ...
触发器实现的主键生成器(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. 多对一...
2. 联合主键(Composite Primary Key) 对于需要多个字段共同作为主键的情况,JPA提供了@Embeddable和@EmbeddedId注解来定义复合主键类。 3. 链接查询(Association Queries) JPA允许在查询中直接引用实体的关联...
触发器实现的主键生成器(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. 多对一...
- **复合主键(Composite Key)**: 当主键由多个字段组成时的处理。 - ** Criteria 查询**: 动态构建查询的API,提供更多灵活性。 **6. JPA实战** 实战部分通常包含实际项目中的应用案例,如: - **Spring Boot + ...
#### 六、复合主键(Composite Primary Key) 实体Bean还可以支持复合主键,即主键由多个属性共同组成。这在某些应用场景中非常有用,例如当实体之间的关联关系较为复杂时。 总结而言,EJB中的注解为开发者提供了一...