Skip to content
Calvin edited this page Nov 13, 2013 · 29 revisions

1.JPA

1.1 自动扫描Entity

彻底删除persistence.xml中Entity的逐一配置,采用自动扫描。因为Weblogic/Jboss这些自带JPA支持的应用服务器有时候会多管闲事的扫描persistence.xml,因此彻底删除掉这个文件是个不错的选择。

	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
		<property name="packagesToScan" value="org.springside.examples.quickstart"/>
	</bean>

1.2 NamingStrategy

数据库的表名,列名与Entity对应的规则,最常见的一个需求是把LOGIN_NAME翻译成loginName,Hibernate提供了ImprovedNamingStrategy, 在JPA中可以这样设置:

	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
		<property name="jpaProperties">
			<props>
				<prop key="hibernate.ejb.naming_strategy">org.hibernate.cfg.ImprovedNamingStrategy</prop>
			</props>
		</property>
	</bean>

1.3 测试

测试所有Mapping的Case

在quickstart里有一个JpaMappingTest,会遍历所有Entity,执行一次select操作看entity上的JPA annotation有没有问题,必备。

flush

hibernate很智能的,事务未提交前都不会轻易执行sql,为了让它执行一下以测试sql是否正确,需要在测试用例里注入一个EntityManager

	@PersistenceContext
	private EntityManager em;

然后在每个save操作后面,跟一句em.flush(); 当然,因为事务是默认回滚的,并不会真正提交到数据库。

1.4 Mapping演示

  1. 所有Entity都继承于同一个定义了主键的IdEntity
  2. Showcase中Team与User的One to Many关系 及反向的User 与 Team的Many to One关系
  3. Showcase中User与Role的Many to Many关系
  4. Showcase中Team与Manager的One to One关系

不过OneToMany的演示中没有适当的用例来设置(cascade = CascadeType.ALL, orphanRemoval = true),另外@Embeddable和@ElementCollection都还没有合适的用例来演示,以后尽量补上。

1.5 Tips

@NamedQuery?

在Entity的开头以@NamedQuery标注用到的sql,好处是JPA的实现会缓存这些JQL的编译结果,坏处就是在本来干净的Entity写满了JQL,而且那个name是一个字符串,不容易在IDE里快速定位到具体的语句。

所以还是在DAO接口里定义JQL算了。

日期字段使用JodaTime ?

Joda Time章节

##2. Hibernate ##2.1 Hibernate二级缓存

  1. Hibernate二级缓存非必需 二级缓存主要用于按主键缓存对象及其关联的Collections。而对sql查询结果的缓存默认是不打开的,除非是非常静态,不怎么变化的数据集。 因为很多普通的CRUD管理系统并不需要非常高的性能还存在集群同步的风险,非常高的性能的系统可能会用memcached并自行精确控制,因此Hibernate自带的2nd系统并不是标配,仅放在showcase里进行演示。

  2. 新版的配置更新,原来的Provider写法

<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider</prop>
<prop key="hibernate.cache.provider_configuration_file_resource_path">ehcache/ehcache-hibernate-local.xml</prop>

hibernate3.3后换成

<prop key="hibernate.cache.region.factory_class">org.hibernate.cache.ehcache.EhCacheRegionFactory</prop>
<prop key="net.sf.ehcache.configurationResourceName">ehcache/ehcache-hibernate-local.xml</prop>

3 SpringSide Modules

暂时的Hibernates里有两个方法:
1.initLazyProperty(Object proxyedPropertyValue), 强制初始化对象的某个lazy load属性

Hibernates.initLazyProperty(user.getGroups()); 
  1. getDialect(DataSource dataSource),通过传入的dataSource,取出jdbc url然后判断出Dialect,这样就成功减少一个配置Dialect的配置项了。 原来的写法
	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
		<property name="jpaProperties">
			<props>
				<prop key="hibernate.dialect">${hibernate.dialect}</prop>
			</props>
		</property>
	</bean>
	<bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter" />

现在改为

	<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
        ...
	</bean>
	<bean id="hibernateJpaVendorAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
		<property name="databasePlatform">
			<bean factory-method="getDialect" class="org.springside.modules.persistence.Hibernates">
				<constructor-arg ref="dataSource"/>
			</bean>
		</property>
	</bean>

##4. Log4jdbc显示SQL 见DataSource章节的Log4jdbc显示SQL

##资料

  • Book:< Pro JPA 2 Mastering the Java Persistence API> 2009 最详细最罗嗦的手册