我正在将我们的webapp从基于XML的IoC,直接Hibernate webapp转换为使用注释和JPA 2.1的webapp。我们的应用服务器是WebLogic 12.1.3,我们使用的是Spring 3.2.13和Hibernate 4.3.9。我们的架构是分层的,每层最终都在自己的JAR文件中。 EAR文件的布局如下:
|-EAR
|-- my-app.ear
|-- my-app.war
|-- lib
|-- my-web.jar
|-- my-services.jar
|-- my-jpa.jar
| |-- META-INF
| |-- persistence.xml
|-- someotherlib.jar
在IoC链的顶部是我们的DelegateFactory,它由Struts1操作使用(稍后我们将升级)。
@Configuration
@ComponentScan({"com.mycompany.myapp.dao.jpa"})
public class DelegateFactory
{
public static DelegateFactory getInstance()
{
if (singleton == null)
{
AnnotationConfigApplicationContext ctx = new AnnotationConfigApplicationContext();
ctx.register(DelegateFactory.class);
ctx.refresh();
singleton = ctx.getBean(DelegateFactory.class);
ctx.close();
}
return singleton;
}
}
IoC在查找Web,服务和DAO bean时起作用,但在尝试查找持久性单元时失败。下面是我们的JPA DAO的基类。它是一个简单的DAO,而不是Spring DAO。为了使它工作,我尝试注入了em和emf。
public abstract class AbstractMyProjectJpaDao extends AbstractJpaTypedDao
{
public static final String PERSISTENCE_UNIT_NAME = "myPU";
@PersistenceUnit(unitName = PERSISTENCE_UNIT_NAME, name = PERSISTENCE_UNIT_NAME)
@Override
public void setEntityManagerFactory(
EntityManagerFactory emf)
{
super.setEntityManagerFactory(emf);
}
@PersistenceContext(unitName = PERSISTENCE_UNIT_NAME, name = PERSISTENCE_UNIT_NAME, type = PersistenceContextType.TRANSACTION)
@Override
public void setEm(
EntityManager em)
{
super.setEm(em);
}
}
到目前为止我们似乎唯一需要的XML文件是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_2_0.xsd"
version="2.0">
<persistence-unit name="myPU" transaction-type="JTA">
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
<jta-data-source>java:/jdbc/myDS</jta-data-source>
(declaration of persistent entities here)
</persistence-unit>
</persistence>
这是失败:
Caused By: org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'myPU' is defined
at org.springframework.beans.factory.support.DefaultListableBeanFactory.getBeanDefinition(DefaultListableBeanFactory.java:575)
at org.springframework.beans.factory.support.AbstractBeanFactory.getMergedLocalBeanDefinition(AbstractBeanFactory.java:1111)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:276)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:195)
at org.springframework.orm.jpa.EntityManagerFactoryUtils.findEntityManagerFactory(EntityManagerFactoryUtils.java:110)
我的猜测是它找不到persistence.xml文件,但根据我所读到的,它位于有效位置。
我错过了什么?
答案 0 :(得分:0)
尝试创建PersistenceConfiguration。 repo.package
指向您可能使用的任何存储库位置,例如Springs CRUD / JPA存储库。 entity.package
指向JPA DAO所在的软件包。
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
basePackages = {"repo.package"},
entityManagerFactoryRef = "entityManagerFactory",
transactionManagerRef = "transactionManager"
)
public class PersistenceConfiguration {
public static final HashSet<String> cacheNames = new HashSet<>();
private static final String[] PACKAGES_TO_SCAN = {"entities.package"};
private static final Properties hibernateProperties;
static {
hibernateProperties = new Properties();
hibernateProperties.setProperty("hibernate.connection.zeroDateTimeBehavior", "convertToNull");
hibernateProperties.setProperty("hibernate.dbcp.maxActive", "50");
hibernateProperties.setProperty("hibernate.dbcp.maxIdle", "10");
hibernateProperties.setProperty("hibernate.dbcp.maxWait", "5000");
hibernateProperties.setProperty("hibernate.jdbc.batch_size property", "50");
hibernateProperties.setProperty("hibernate.connection.charSet", "UTF-8");
hibernateProperties.setProperty("hibernate.connection.characterEncoding", "UTF-8");
hibernateProperties.setProperty("hibernate.connection.useUnicode", "true");
}
@Bean
public DataSource dataSource(){
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName("database.driver");
dataSource.setUrl("database url");
dataSource.setUsername( "tutorialuser" );
dataSource.setPassword( "tutorialmy5ql" );
return dataSource;
}
/**
* Create the entity manager factory bean used in the database connection
* @return entityManagerFactoryBean
*/
@Primary
@Bean
public LocalContainerEntityManagerFactoryBean entityManagerFactory() {
LocalContainerEntityManagerFactoryBean lef = new LocalContainerEntityManagerFactoryBean();
lef.setDataSource(dataSource);
lef.setJpaVendorAdapter(portalJpaVendorAdapter());
lef.setPackagesToScan(PACKAGES_TO_SCAN);
lef.setJpaProperties(hibernateProperties);
lef.setPersistenceUnitName("my_pu");
return lef;
}
/**
* Create the session factory bean
* @return sessionFactoryBean
*/
@Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionBean = new LocalSessionFactoryBean();
sessionBean.setDataSource(dataSource);
sessionBean.setPackagesToScan(PACKAGES_TO_SCAN);
sessionBean.setHibernateProperties(hibernateProperties);
return sessionBean;
}
/**
* Create the JPA Vendor adaptor bean that is used in the entity manager factory
* @return jpaVendorAdaptor
*/
@Primary
@Bean
public JpaVendorAdapter jpaVendorAdapter() {
HibernateJpaVendorAdapter hibernateJpaVendorAdapter = new HibernateJpaVendorAdapter();
hibernateJpaVendorAdapter.setShowSql(false);
hibernateJpaVendorAdapter.setGenerateDdl(false);
hibernateJpaVendorAdapter.setDatabase(Database.MYSQL);
return hibernateJpaVendorAdapter;
}
/**
* Create the transaction manager bean
* @return transactionManager
*/
@Primary
@Bean
public PlatformTransactionManager transactionManager() {
JpaTransactionManager manager = new JpaTransactionManager();
manager.setEntityManagerFactory(portalEntityManagerFactory().getObject());
return new JpaTransactionManager();
}
}
如果您已经创建了数据源bean,则可以自动装配它而不是直接创建bean。
答案 1 :(得分:0)
问题的第一部分是我没有插入EntityManagerFactory。我最终用这个创建了一个dao-beans.xml文件:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPU" />
</bean>
然后我必须将@ImportResource注释添加到我的DelegateFactory中,以便找到XML文件。
@Configuration
@ComponentScan({"com.mycompany.myapp.dao.jpa"})
@ImportResource("classpath:dao-beans.xml")
public class DelegateFactory
{
...
}
我还必须从&#34; java:/ jdbc / myDS&#34;更改persistence.xml中数据源的JNDI名称。只是&#34; jdbc / myDS&#34;。我认为这是一个WebLogic的事情。