`
kylinsoong
  • 浏览: 236144 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

JPA dev: 几个问题总结

阅读更多

最近工作中遇到几个与JPA相关的问题,本文通过一个例子总结一下这些问题。

1 给出一个例子:

如下图表式Persistent Context中所有实体的关系图:



 从图中可以看到:

所有实体间对应关系都是单向的;

User和Event,User和Friend,Event和Property,Wife和Pet,Pet和Property关系为一对多关系;

User和UserCard,Friend和UserCard,Wife和UserCard,User和Wife之间的关系是一对一关系;

http://kylinsoong.iteye.com/blog/807937所示创建工程;

贴出相关代码:

package com.tibco.hibernate.po;

import java.util.Calendar;
import java.util.List;
import java.util.Set;

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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.ForeignKey;


@Entity(name="User")
@Table(name="k_user")
public class User {
	private Long id;
	private String name;
	private List<Event> events;
	private List<Friend> friends;
	private UserCard userCard;
	private Wife wife;
	private Calendar createdDate;
	private Boolean isMale;

	@Column
	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@OneToMany (
			targetEntity=com.tibco.hibernate.po.Event.class,
			fetch=FetchType.LAZY,
			cascade = { CascadeType.ALL })
	@Cascade( { org.hibernate.annotations.CascadeType.ALL } ) 
	@JoinTable(name="k_user_event", 
			joinColumns = @JoinColumn(name = "USER_ID"), 
			inverseJoinColumns = @JoinColumn(name = "EVENT_ID"))
	@ForeignKey(name = "k_user_event_FK", 
			inverseName = "k_user_event_FK_R")
	public List<Event> getEvents() {
		return events;
	}

	public void setEvents(List<Event> events) {
		this.events = events;
	}

	@OneToMany (
			targetEntity=com.tibco.hibernate.po.Friend.class,
			fetch=FetchType.EAGER,
			cascade = { CascadeType.ALL })
	@Cascade( { org.hibernate.annotations.CascadeType.ALL } ) 
	@JoinTable(name="k_user_friend", 
			joinColumns = @JoinColumn(name = "USER_ID"), 
			inverseJoinColumns = @JoinColumn(name = "FRIEND_ID"))
	@ForeignKey(name = "k_user_friend_FK", 
			inverseName = "k_user_friend_FK_R")
	public List<Friend> getFriends() {
		return friends;
	}

	public void setFriends(List<Friend> friends) {
		this.friends = friends;
	}

	@OneToOne(
			targetEntity = com.tibco.hibernate.po.UserCard.class, 
    		fetch = FetchType.EAGER, 
    		cascade = { CascadeType.ALL })
    @Cascade( { org.hibernate.annotations.CascadeType.ALL } )    		
	@JoinColumn(name = "UserCard_id")
	@ForeignKey(name = "USER_TO_USERCARD_FK")  
	public UserCard getUserCard() {
		return userCard;
	}

	public void setUserCard(UserCard userCard) {
		this.userCard = userCard;
	}

	@OneToOne(
			targetEntity = com.tibco.hibernate.po.Wife.class, 
    		fetch = FetchType.EAGER, 
    		cascade = { CascadeType.ALL })
    @Cascade( { org.hibernate.annotations.CascadeType.ALL } )    		
	@JoinColumn(name = "Wife_id")
	@ForeignKey(name = "USER_TO_WIFE_FK") 
	public Wife getWife() {
		return wife;
	}

	public void setWife(Wife wife) {
		this.wife = wife;
	}

	@Column(name = "CREATEDDATE")
    @Temporal(TemporalType.DATE)
	public Calendar getCreatedDate() {
		return createdDate;
	}

	public void setCreatedDate(Calendar createdDate) {
		this.createdDate = createdDate;
	}

	@Column
	public Boolean getIsMale() {
		return isMale;
	}

	public void setIsMale(Boolean isMale) {
		this.isMale = isMale;
	}


}

 

package com.tibco.hibernate.po;

import java.util.List;

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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.ForeignKey;

@Entity(name="Event")
@Table(name="k_event")
public class Event {
	private Long id;
	private String name;
	private List<Property> properties;

	@Column
	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@OneToMany (
			targetEntity=com.tibco.hibernate.po.Property.class,
			fetch=FetchType.LAZY,
			cascade = { CascadeType.ALL })
	@Cascade( { org.hibernate.annotations.CascadeType.ALL } ) 
	@JoinTable(name="k_event_property", 
			joinColumns = @JoinColumn(name = "EVENT_ID"), 
			inverseJoinColumns = @JoinColumn(name = "PROPERTY_ID"))
	@ForeignKey(name = "k_event_property_FK", 
			inverseName = "k_event_property_FK_R")
	public List<Property> getProperties() {
		return properties;
	}

	public void setProperties(List<Property> properties) {
		this.properties = properties;
	}

}

 

package com.tibco.hibernate.po;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity(name="Property")
@Table(name="k_property")
public class Property {
	private Long id;
	private String name;
	
	@Column
	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public String toString() {
		return "Property [id=" + id + ", name=" + name + "]";
	}

}

 

package com.tibco.hibernate.po;

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.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.ForeignKey;

@Entity(name="Friend")
@Table(name="k_friend")
public class Friend {
	private Long id;
	private String name;
	private UserCard userCard;

	@Column
	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	@OneToOne(
			targetEntity = com.tibco.hibernate.po.UserCard.class, 
    		fetch = FetchType.EAGER, 
    		cascade = { CascadeType.ALL })
    @Cascade( { org.hibernate.annotations.CascadeType.ALL } )    		
	@JoinColumn(name = "UserCard_id")
	@ForeignKey(name = "FRIEND_TO_USERCARD_FK")  
	public UserCard getUserCard() {
		return userCard;
	}

	public void setUserCard(UserCard userCard) {
		this.userCard = userCard;
	}

	public String toString() {
		return "Friend [id=" + id + ", name=" + name + "]";
	}
}

 

package com.tibco.hibernate.po;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity(name="UserCard")
@Table(name="k_userCard")
public class UserCard {
	private Long id;
	private String cardNumber;

	@Column
	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column
	public String getCardNumber() {
		return cardNumber;
	}

	public void setCardNumber(String cardNumber) {
		this.cardNumber = cardNumber;
	}
}

 

package com.tibco.hibernate.po;

import java.util.List;

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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.ForeignKey;

@Entity(name="Wife")
@Table(name="k_wife")
public class Wife {
	private Long id;
	private String name;
	private UserCard userCard;
	private List<Pet> pets;

	@Column
	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@OneToOne(
			targetEntity = com.tibco.hibernate.po.UserCard.class, 
    		fetch = FetchType.EAGER, 
    		cascade = { CascadeType.ALL })
    @Cascade( { org.hibernate.annotations.CascadeType.ALL } )    		
	@JoinColumn(name = "UserCard_id")
	@ForeignKey(name = "Wife_TO_USERCARD_FK")
	public UserCard getUserCard() {
		return userCard;
	}

	public void setUserCard(UserCard userCard) {
		this.userCard = userCard;
	}

	@OneToMany (
			targetEntity=com.tibco.hibernate.po.Pet.class,
			fetch=FetchType.LAZY,
			cascade = { CascadeType.ALL })
	@Cascade( { org.hibernate.annotations.CascadeType.ALL } ) 
	@JoinTable(name="k_wife_pet", 
			joinColumns = @JoinColumn(name = "WIFE_ID"), 
			inverseJoinColumns = @JoinColumn(name = "PET_ID"))
	@ForeignKey(name = "k_wife_pet_FK", 
			inverseName = "k_wife_pet_FK_R")
	public List<Pet> getPets() {
		return pets;
	}

	public void setPets(List<Pet> pets) {
		this.pets = pets;
	}

	
	
}

 

package com.tibco.hibernate.po;

import java.util.List;

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.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.ForeignKey;

@Entity(name="Pet")
@Table(name="k_pet")
public class Pet {

	private Long id;
	private String name;
	private List<Property> properties;

	@Column
	@Id
	@GeneratedValue
	public Long getId() {
		return id;
	}

	public void setId(Long id) {
		this.id = id;
	}

	@Column
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	@OneToMany (
			targetEntity=com.tibco.hibernate.po.Property.class,
			fetch=FetchType.LAZY,
			cascade = { CascadeType.ALL })
	@Cascade( { org.hibernate.annotations.CascadeType.ALL } ) 
	@JoinTable(name="k_pet_property", 
			joinColumns = @JoinColumn(name = "EVENT_ID"), 
			inverseJoinColumns = @JoinColumn(name = "PROPERTY_ID"))
	@ForeignKey(name = "k_pet_property_FK", 
			inverseName = "k_pet_property_FK_R")
	public List<Property> getProperties() {
		return properties;
	}

	public void setProperties(List<Property> properties) {
		this.properties = properties;
	}
}

 

贴出persistence.xml配置:

<persistence xmlns="http://java.sun.com/xml/ns/persistence"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
	xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
	version="1.0">
	<persistence-unit name="com.tibco.hibernate.po">
		<provider>org.hibernate.ejb.HibernatePersistence</provider>
		<class>com.tibco.hibernate.po.Event</class>
		<class>com.tibco.hibernate.po.Friend</class>
		<class>com.tibco.hibernate.po.Pet</class>
		<class>com.tibco.hibernate.po.Property</class>
		<class>com.tibco.hibernate.po.User</class>
		<class>com.tibco.hibernate.po.UserCard</class>
		<class>com.tibco.hibernate.po.Wife</class>
		<properties>
	</properties>
				
	</persistence-unit>
</persistence>

 

数据库配置信息:

hibernate.dialect=org.hibernate.dialect.Oracle10gDialect

#connection
hibernate.connection.driver_class=oracle.jdbc.driver.OracleDriver
hibernate.connection.username=IPC113
hibernate.connection.password=bpm
hibernate.connection.url=jdbc:oracle:thin:@//192.168.68.120:1521/orcl

#pool 
hibernate.c3p0.min_size=1
hibernate.c3p0.max_size=20
hibernate.c3p0.timeout=1800
hibernate.c3p0.max_statements=50

 

在J2SE下使用JPA需要EntityManager对Persistent context中的实体与数据库同步,EntityManager由EntityManagerFactory产生,给出产生EntityManagerFactory的工具类:

package com.tibco.hibernate.jpa;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.Properties;

import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class JPAUtil {

	public static final String POJO_PACKAGE = "com.tibco.hibernate.po";

	public static EntityManagerFactory createEMF(String dbproperties)
			throws IOException {
		Properties persistenceProperties = loadProperties(dbproperties);

		return Persistence.createEntityManagerFactory(POJO_PACKAGE,
				persistenceProperties);
	}
	
	public static Properties loadProperties(String dbproperties) throws IOException {
		Properties persistenceProperties = loadFromResource(dbproperties+".properties");
		
		return persistenceProperties;
	}

	private static Properties loadFromResource(String resourceName)
			throws IOException {
		Properties p = new Properties();
		InputStream is = new FileInputStream(new File(resourceName));
		try {
			p.load(is);
		} finally {
			try {
				if (is != null)
					is.close();
			} catch (IOException ignored) {
			}
		}

		return p;
	}

}

 

先在向数据库中插入一条数据:

public class JPAClient {

	public static void main(String[] args) throws Throwable {
		EntityManagerFactory emf = JPAUtil.createEMF("oracle");
		EntityManager em = emf.createEntityManager();
		EntityTransaction t = em.getTransaction();
		t.begin();
		
		User user = getUser();
		em.persist(user);
		
		t.commit();
		em.close();
		emf.close();
	}

private static boolean isProxyProperty(Object obj) throws Throwable {
	String name = obj.getClass().getName();
	return name.contains("_$$_javassist_") || name.contains("org.hibernate.collection.PersistentBag");
}

	private static User getUser() {
		List<Event> events = getEventList();
		List<Friend> friends = getFriendList();
		UserCard userCard = new UserCard();
		userCard.setCardNumber("user usercard number");
		Wife wife = getWife();
		User user = new User();
		user.setName("Kylin Soong");
		user.setEvents(events);
		user.setEvents(events);
		user.setFriends(friends);
		user.setIsMale(Boolean.TRUE);
		user.setUserCard(userCard);
		user.setCreatedDate(Calendar.getInstance());
		user.setWife(wife);
		
		return user;
	}

	private static Wife getWife() {
		UserCard userCard = new UserCard();
		userCard.setCardNumber("Wife usercard number");
		List<Pet> pets = getPetList();
		Wife wife = new Wife();
		wife.setName("Bitch Soong");
		wife.setUserCard(userCard);
		wife.setPets(pets);
		return wife;
	}

	private static List<Pet> getPetList() {
		List<Pet> pets = new ArrayList<Pet>();
		Pet p1 = new Pet();
		p1.setName("dog 1");
		p1.setProperties(getPropertyList(p1.getName()));
		Pet p2 = new Pet();
		p2.setName("dog 2");
		p2.setProperties(getPropertyList(p2.getName()));
		pets.add(p2);
		pets.add(p1);
		return pets;
	}

	private static List<Friend> getFriendList() {
		List<Friend> friends = new ArrayList<Friend>();
		Friend f1 = new Friend();
		f1.setName("friend1");
		UserCard uc1 = new UserCard();
		uc1.setCardNumber("friend1-usercard-number");
		f1.setUserCard(uc1);
		
		Friend f2 = new Friend();
		f2.setName("friend2");
		UserCard uc2 = new UserCard();
		uc2.setCardNumber("friend2-usercard-number");
		f2.setUserCard(uc2);
		friends.add(f1);
		friends.add(f2);
		return friends;
	}

	private static List<Event> getEventList() {
		List<Event> events = new ArrayList<Event>();
		Event e = null;
		e = new Event();
		e.setName("Cool");
		e.setProperties(getPropertyList(e.getName()));
		events.add(e);
		e = new Event();
		e.setName("Hot");
		e.setProperties(getPropertyList(e.getName()));
		events.add(e);
		e = new Event();
		e.setName("Cold");
		e.setProperties(getPropertyList(e.getName()));
		events.add(e);
		
		return events;
	}

	private static List<Property> getPropertyList(String name) {
		List<Property> props = new ArrayList<Property>();
		Property p1 = new Property();
		p1.setName(name + " property 1");
		Property p2 = new Property();
		p2.setName(name + " property 2");
		props.add(p1);
		props.add(p2);
		return props;
	}

}

 

这时一条数据插入到数据库,

到此词例子结束,接下来的一些测试全基于此例子

  • 大小: 24.1 KB
0
0
分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics