Spring JPA:NoSuchBeanDefinitionException:没有名为';myPU';定义
我正在将我们的webapp从一个基于XML的IoC、直接的Hibernate webapp转换为一个使用注释和jpa2.1的webapp。我们的应用服务器是WebLogic 12.1.3,我们使用的是Spring 3.2.13和Hibernate 4.3.9。我们的体系结构是分层的,每一层都以自己的JAR文件结束。EAR文件的布局如下所示:Spring JPA:NoSuchBeanDefinitionException:没有名为';myPU';定义,spring,hibernate,jpa,spring-bean,Spring,Hibernate,Jpa,Spring Bean,我正在将我们的webapp从一个基于XML的IoC、直接的Hibernate webapp转换为一个使用注释和jpa2.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
|-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 actions使用它(我们稍后会升级)
IoC在查找web、服务和DAOBean时工作,但在尝试查找持久化单元时失败。下面是我们的JPA 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);
}
}
到目前为止,我们似乎只需要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>
我猜它就是找不到persistence.xml文件,但根据我读到的,它位于一个有效的位置
我缺少什么?尝试创建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();
}
}
@配置
@启用事务管理
@授权代理(
basePackages={“repo.package”},
entityManagerFactoryRef=“entityManagerFactory”,
transactionManagerRef=“transactionManager”
)
公共类持久化配置{
public static final HashSet cacheNames=new HashSet();
私有静态最终字符串[]包\u到\u扫描={“entities.package”};
私有静态最终属性hibernateProperties;
静止的{
hibernateProperties=新属性();
hibernateProperties.setProperty(“hibernate.connection.zeroDateTimeBehavior”、“ConvertToFull”);
setProperty(“hibernate.dbcp.maxActive”,“50”);
setProperty(“hibernate.dbcp.maxIdle”,“10”);
setProperty(“hibernate.dbcp.maxWait”,“5000”);
hibernateProperties.setProperty(“hibernate.jdbc.batch_size属性”,“50”);
hibernateProperties.setProperty(“hibernate.connection.charSet”,“UTF-8”);
hibernateProperties.setProperty(“hibernate.connection.characterEncoding”,“UTF-8”);
hibernateProperties.setProperty(“hibernate.connection.useUnicode”,“true”);
}
@豆子
公共数据源数据源(){
DriverManager数据源dataSource=新的DriverManager数据源();
dataSource.setDriverClassName(“database.driver”);
setUrl(“数据库url”);
setUsername(“tutorialuser”);
setPassword(“tutorialmy5ql”);
返回数据源;
}
/**
*创建数据库连接中使用的实体管理器工厂bean
*@return entityManagerFactoryBean
*/
@初级的
@豆子
public LocalContainerEntityManagerFactoryBean entityManagerFactory(){
LocalContainerEntityManagerFactoryBean lef=新的LocalContainerEntityManagerFactoryBean();
lef.setDataSource(数据源);
lef.setJpaVendorAdapter(portalJpaVendorAdapter());
lef.设置包扫描(包到包扫描);
lef.setJpaProperties(hibernateProperties);
lef.setPersistenceUnitName(“my_pu”);
返回lef;
}
/**
*创建会话工厂bean
*@return sessionFactoryBean
*/
@豆子
公共LocalSessionFactoryBean sessionFactory(){
LocalSessionFactoryBean sessionBean=新的LocalSessionFactoryBean();
setDataSource(dataSource);
setPackagesToScan(包到扫描);
setHibernateProperties(hibernateProperties);
返回sessionBean;
}
/**
*创建实体管理器工厂中使用的JPA供应商适配器bean
*@return-jpa适配器
*/
@初级的
@豆子
公共JpaVendorAdapter JpaVendorAdapter(){
hibernatejbavendorapter hibernatejbavendorapter=新的hibernatejbavendorapter();
hibernatejbavendorapter.setShowSql(false);
HibernateJavaEndorapter.setGenerateDdl(false);
setDatabase(Database.MYSQL);
返回HibernateJavaEndorapter;
}
/**
*创建事务管理器bean
*@returntransactionmanager
*/
@初级的
@豆子
公共平台transactionManager transactionManager(){
JpaTransactionManager=新的JpaTransactionManager();
setEntityManagerFactory(portalEntityManagerFactory().getObject());
返回新的JpaTransactionManager();
}
}
如果已经创建了一个数据源bean,那么可以自动连接它,而不是直接创建bean。问题的第一部分是我没有插入EntityManagerFactory。我最终创建了一个dao-beans.xml文件,其中包含以下内容:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPU" />
</bean>
我还必须将persistence.xml中数据源的JNDI名称从“java:/jdbc/myDS”更改为“jdbc/myDS”。我认为这是一个WebLogic问题。谢谢,但这是一个解决方法,而不是实际问题的解决方案。如果我需要这样做,我会的(谢谢你的代码),但我真的想知道为什么它不能按原样工作。将persistence.xml复制到我的应用程序时会出现同样的问题。war/WEB-INF/classes在我尝试@PersistenceUnit(unitName=“lib/my jpa.jar#myPU”,name=“myPU”)时不起作用
@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 id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean">
<property name="persistenceUnitName" value="myPU" />
</bean>
@Configuration
@ComponentScan({"com.mycompany.myapp.dao.jpa"})
@ImportResource("classpath:dao-beans.xml")
public class DelegateFactory
{
...
}