`
kylinsoong
  • 浏览: 240722 次
  • 性别: 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
分享到:
评论

相关推荐

    EJB Dev 1: EJB入门例子

    在查看`com.ejb.helloworld.client`和`com.ejb.helloworld`的源码时,你可以关注以下几个点: - Bean类的注解,如`@Remote`或`@Local`接口定义。 - Bean的实现方法,它们包含了业务逻辑。 - 客户端如何查找和...

    电子医疗系统Web项目-使用Spring Boot安全-JPA-Rest-Thymeleaf-HQL:Project生物医学和“医院”领域的项目,涵盖这三个领域的各个领域various 。该项目使用:hot_beverage:Spring Framework,Hibernate,JPA,Rest,JSP以及:desktop_computer_selector:(Post-Dev Data-Science,Big-data,ML等):thermometer_selector:[用于Hackathon,CSI

    生物医学与医院领域的项目,涵盖了这三个领域的各个领域。该项目还使用了Spring Framework,Hibernate,JPA,Rest,JSP,以及(后开发数据科学,大数据,机器学习等) [用于Hackathon,CSI和SIH] Docker整合 ...

    掌握用UML进行面向对象的分析和设计:DEV475_14_DatabaseDesign.pdf

    在实际设计中,我们需要考虑以下几个方面: 1. 明确持久化类的属性和关联,确保它们可以映射到合适的数据库表和字段。 2. 分析类的行为,确定哪些行为应该保留在应用程序中,哪些可以下放到数据库中,如触发器、存储...

    一个完整的spring boot项目

    在“一个完整的spring boot项目”中,我们可以深入学习以下几个关键知识点: 1. **Spring Boot 核心特性**: - 自动配置:Spring Boot 会根据项目依赖自动配置相应的 Bean,极大地减少了手动配置的工作量。 - ...

    springboot入门项目

    本入门项目主要涵盖了以下几个核心知识点: 1. **Spring Boot 基础**: - **起步依赖(Starter Dependency)**:Spring Boot 通过起步依赖来简化 Maven 或 Gradle 配置,每个起步依赖都包含了特定功能所需的所有...

    springboot项目整合

    在本项目中,"springboot项目整合"是一个关键主题,涉及到Spring Boot框架与其他技术的集成。Spring Boot以其简化Java应用程序的初始设置和操作而闻名,它通过预设配置和自动配置来快速启动开发。让我们深入探讨一下...

    springboot教程视图学习相关资源

    在 "springboot教程视图学习相关资源" 中,我们可以关注以下几个关键知识点: 1. **SpringBoot 启动流程**:了解 SpringBoot 应用如何启动,包括自动配置、主启动类以及 SpringApplication.run 方法的作用。 2. **...

    springboot-demo:springboot演示

    在"springboot-demo"项目中,我们通常会看到以下几个核心概念和技术: 1. **自动配置**:SpringBoot的一大特性是它的自动配置能力。通过扫描`@EnableAutoConfiguration`注解的启动类,SpringBoot会根据类路径中的...

    SpringBoot知识点整理思维导图

    在本思维导图中,主要涵盖了以下几个核心知识点: 1. **快速配置**:Spring Boot的核心理念之一就是“约定优于配置”,它通过自动配置类和起步依赖来简化项目设置。开发者只需通过添加相应的starter pom依赖,即可...

    springboot环境配置

    环境配置主要包括以下几个方面: 1. **属性配置**:SpringBoot使用`application.properties`或`application.yml`文件来管理配置。这些文件通常位于`src/main/resources`目录下。你可以在这里设置数据库连接、服务器...

    基于SpringBoot + vue + Element-UI 搭建的个人博客系统.zip

    这是一个基于SpringBoot、Vue.js和Element-UI框架搭建的个人博客系统的源代码包。这个项目适合初学者和学生,作为...同时,这也是一个很好的实战项目,可以帮助你更好地理解和运用所学知识,提高解决实际问题的能力。

    PODInterdisciplinarQI:工作专长BamBam

    项目可能包括以下几个关键知识点: 1. **Java编程**:掌握基础的Java语法、类与对象、异常处理、集合框架、多线程、输入输出流等,以及更高级的主题如Spring框架、JPA(Java Persistence API)用于数据库操作,以及...

    notification-service

    通知服务通常由以下几个核心部分组成: 1. **事件生成**:当系统中发生特定事件(如用户下单、支付成功)时,会产生相应的通知事件。 2. **通知模板**:为了提供灵活的通知格式,服务通常会支持多种模板,以便根据...

    insan-kaynaklari-yonetim-sistemi:使用 Java 和 React 创建的 hrms 项目

    项目结构可能包括以下几个关键部分: 1. 后端源码:包含了Spring Boot应用程序的Java类,如控制器、服务、模型实体等。 2. 前端源码:包含React组件、样式表、路由配置等,可能还有Webpack等构建工具的配置文件。 3....

    demo-spring-boot

    - "demo-spring-boot-main"可能是项目的主要源代码目录,通常包含以下几个部分: - `src/main/java`: 项目的Java源代码,通常会有`com.example.demo`这样的包结构,其中`DemoApplication`是主启动类。 - `src/...

    quarkus-minimal

    在这个目录下,你可能会找到以下几个关键部分: 1. `src/main/java` - 这里包含Java源代码文件,通常有`io.quarkus.app`或其他自定义的包结构,这是应用的主要入口点,比如`App.java`或`Application.java`,它使用...

    spring-services-versioning:该示例的目的是演示Spring REST服务的版本控制

    该应用程序由一个控制器组成,该控制器使用Spring Data JPA API向H2数据库发出请求。 用法 有几种方法可以测试应用程序。 使用Maven mvn spring-boot:run -Dspring.profiles.active=dev 或者 使用Bash命令 mvn ...

Global site tag (gtag.js) - Google Analytics