在将对象持久化到数据中的时候,先是按照正常的顺序开发,比如
第一步:创建JPA persistence.xml配置文件
第二步:创建EntityManagerFactory、EntityManager
第三步:创建实体类,使用annotation来描述实体类跟数据库表之间的一一映射关系
第四步:使用JPA API完成数据的增加、删除、修改和查询操作。
按照这样的开发顺序,运行程序是没有问题的。但是当我需要把这些开发完的应用程序打成jar包,将jar包放到其他的应用程序中,再次运行就会出现问题。当然persistence.xml配置文件也会从jar包中移动到新的应用程序的配置路径下。
异常1:persistence.xml配置文件的路径不对
异常信息:
javax.persistence.PersistenceException: No Persistence provider for EntityManager named klmsdb
解决方法:在新工程的根目录下创建一个source folder,source folder的名称为config,当然这个名称可以自己命名,再在config目录下创建META-INF,在META-INF下创建配置文件persistence.xml,myeclipse会在bin编译目录下创建文件META-INF\persistence.xml,当程序在创建EntityManagerFactory的时候,搜索persistence.xml配置文件的路径就是META-INF\persistence.xml。
异常2:找不到实体异常
异常信息:
java.lang.IllegalArgumentException: Unknown entity: ch.ntb.inf.klms.model.objects.managed.SymmetricKey
SymmetricKey是需要向数据库中添加的对象,我们在将应用程序打成jar包之后,jpa的实现者(我用的是hibernate作为jpa的实现)就不会去扫描jar包中的注解,比如@Entity,这样jpa的实现者就认为正在插入数据库的对象,是一个未知的实体。
解决方法:在配置文件中添加<jar-file>标签,告诉jpa的实现者去扫描该标签指定的jar文件中的实例类。
比如我的配置如下:
<persistence-unit name="klmsdb" transaction-type="RESOURCE_LOCAL">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<jar-file>libs/KeyManager.jar</jar-file>
<properties>
<property name="hibernate.dialect" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="hibernate.connection.driver_class" value="org.gjt.mm.mysql.Driver" />
<property name="hibernate.connection.username" value="test" />
<property name="hibernate.connection.password" value="123456" />
<property name="hibernate.connection.url" value="jdbc:mysql://localhost:3306/klmsdb?useUnicode=true&characterEncoding=UTF-8" />
<property name="hibernate.hbm2ddl.auto" value="create" />
</properties>
</persistence-unit>
KeyManager.jar包就是自己开发的实体类存放的jar包。