在分享之前先给大家看两个异常,应该说这一类的异常还是很常见的,主要原因是jar包冲突
异常1:
java.lang.NoSuchFieldError: INSTANCE
at org.hibernate.type.BasicTypeRegistry.<init>(BasicTypeRegistry.java:94)
at org.hibernate.type.TypeResolver.<init>(TypeResolver.java:59)
at org.hibernate.cfg.Configuration.<init>(Configuration.java:250)
at org.hibernate.cfg.Configuration.<init>(Configuration.java:302)
at org.hibernate.cfg.AnnotationConfiguration.<init>(AnnotationConfiguration.java:108)
at org.hibernate.ejb.Ejb3Configuration.<clinit>(Ejb3Configuration.java:107)
at org.hibernate.ejb.HibernatePersistence.createEntityManagerFactory(HibernatePersistence.java:124)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:52)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:34)
at org.lxh.util.JpaUtil.<clinit>(JpaUtil.java:10)
at org.lxh.test.Test.testInsert(Test.java:20)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:47)
这个异常主要出现在hibernate3.6或更高版本,解决办法是删除hibernate-annotations.jar和hibernate-commons-annotations.jar
因为hibernate3.6包里已经包含以上两包了
异常2:
Caused by: java.lang.NoSuchMethodError: javax.persistence.OneToMany.orphanRemoval()Z
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1912)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:796)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:707)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processAnnotatedClassesQueue(Configuration.java:4035)
at org.hibernate.cfg.Configuration$MetadataSourceQueue.processMetadata(Configuration.java:3989)
at org.hibernate.cfg.Configuration.secondPassCompile(Configuration.java:1398)
at org.hibernate.cfg.Configuration.buildMappings(Configuration.java:1375)
at org.springframework.orm.hibernate3.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:717)
at org.springframework.orm.hibernate3.AbstractSessionFactoryBean.afterPropertiesSet(AbstractSessionFactoryBean.java:188)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1514)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1452)
... 65 more
该异常也是jar包冲突导致,主要还是出现在hibernate3.6或更高版本,解决办法是删除ejb3-persistence.jar
一 一对多关联关系
1. 部门的员工的实体类
package org.lxh.info;
import java.util.*;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToMany;
@Entity
public class Depart {
private Integer id;
private String departName;
private String departNum;
private Set<Employee> emp;
@Id @GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Column(length=50,nullable=false,unique=true)
public String getDepartName() {
return departName;
}
public void setDepartName(String departName) {
this.departName = departName;
}
public String getDepartNum() {
return departNum;
}
public void setDepartNum(String departNum) {
this.departNum = departNum;
}
@OneToMany(cascade={CascadeType.REMOVE,CascadeType.PERSIST},mappedBy="depart")
public Set<Employee> getEmp() {
return emp;
}
public void setEmp(Set<Employee> emp) {
this.emp = emp;
}
}
一对多关联使用的注解是@OneToMany,cascade就不解释了,mappedBy属性主要用在关系被维护端,在这里就是一的这一边,mappedBy="depart"表明在关系维护端对应的属性为depart
package org.lxh.info;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
@Entity
public class Employee {
private Integer id;
private String num;
private String name;
private Depart depart;
@Id @GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNum() {
return num;
}
public void setNum(String num) {
this.num = num;
}
@Column(nullable=false,length=50)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@ManyToOne
@JoinColumn(name="depart_id")
public Depart getDepart() {
return depart;
}
public void setDepart(Depart depart) {
this.depart = depart;
}
}
Employee作为关系维护端负责外键字段或外键记录的更新,体现在数据库中则为从表,里面含有一个外键和depart相对应。@JoinColumn用来指定外键的列名,从程序可以看出这里的外键列名为depart_id
2 使用单元测试保存数据
package org.lxh.test;
import static org.junit.Assert.*;
import java.util.*;
import javax.persistence.EntityManager;
import javax.persistence.EntityTransaction;
import javax.persistence.Query;
import org.lxh.info.Depart;
import org.lxh.info.Employee;
import org.lxh.util.JpaUtil;
public class Test {
@org.junit.Test
public void testInsert() {
EntityManager em=null;
EntityTransaction tx=null;
try{
em=JpaUtil.getEntityManager();
tx=em.getTransaction();
tx.begin();
Depart d=new Depart();
d.setDepartName("质量管理部");
d.setDepartNum("DP0001");
Employee e=new Employee();
e.setDepart(d);
e.setName("李明");
e.setNum("C0001");
Set<Employee> emps=new HashSet<Employee>();
emps.add(e);
d.setEmp(emps);;
em.persist(d);
tx.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
if(em!=null){
em.close();
}
}
}
}
下面是打印出的sql语句:
Hibernate:
insert
into
Depart
(departName, departNum)
values
(?, ?)
Hibernate:
insert
into
Employee
(depart_id, name, num)
values
(?, ?, ?)
这样数据就保存成功了,其他操作暂时忽略,大家可以自己写一写
二 一对一关联关系
一对一关联使用的场合相对较少,好多人都会把两个表并为一个,字段看起来很多但是操作起来着实方便
1 先来看看实体,我的例子是人员和人员信息详细表的对于关系
package org.lxh.info;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
@Entity
@Table(name = "m_users")
public class User {
private int id;
private String name;
private Date birthday;
private Sex sex;
private UserDetails userDetails;
@Id
@GeneratedValue
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
@Column(length=20,nullable=false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
@Temporal(TemporalType.DATE)
public Date getBirthday() {
return birthday;
}
public void setBirthday(Date birthday) {
this.birthday = birthday;
}
@Enumerated(EnumType.STRING)
@Column(length=5,nullable=false)
public Sex getSex() {
return sex;
}
public void setSex(Sex sex) {
this.sex = sex;
}
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="detailsId")
public UserDetails getUserDetails() {
return userDetails;
}
public void setUserDetails(UserDetails userDetails) {
this.userDetails = userDetails;
}
}
对于一对一关联关系,代码编写者可以根据自已的意愿或业务需要选择任意一方作为关系维护方,我这里选择的人员信息详细作为关系维护方
package org.lxh.info;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.OneToOne;
@Entity
public class UserDetails {
private Integer id;
private String introduce;
private String cardNum;
private User user;
@Id @GeneratedValue
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
@Lob
public String getIntroduce() {
return introduce;
}
public void setIntroduce(String introduce) {
this.introduce = introduce;
}
public String getCardNum() {
return cardNum;
}
public void setCardNum(String cardNum) {
this.cardNum = cardNum;
}
@OneToOne(mappedBy="userDetails",cascade=CascadeType.MERGE)
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}
到这里实体就编写好了
2 一对一的保存操作
@org.junit.Test
public void testInsert() {
EntityManager em=null;
EntityTransaction tx=null;
try{
em=JpaUtil.getEntityManager();
tx=em.getTransaction();
tx.begin();
User u=new User();
u.setBirthday(new Date());
u.setName("潘玮柏");
u.setSex(Sex.MAN);
UserDetails detail=new UserDetails();
detail.setCardNum("562923");
detail.setIntroduce("暂无");
detail.setUser(u);
u.setUserDetails(detail);
em.persist(u);
tx.commit();
}catch(Exception e){
e.printStackTrace();
}finally{
if(em!=null){
em.close();
}
}
}
打印出来的sql语句如下:
Hibernate:
insert
into
UserDetails
(cardNum, introduce)
values
(?, ?)
Hibernate:
insert
into
m_users
(birthday, name, sex, detailsId)
values
(?, ?, ?, ?)
是不是很简单呢
