2016-11-04 5 views
0

Я настраиваю приложение, которое принимает вызов REST, а затем выполняет некоторую работу DB. Я пытаюсь использовать Spring, чтобы делать все через аннотации, за исключением того, что я хотел бы сохранить файл persistence.xml. Тем не менее, меня забрасывают ошибкой, что нет бина, называемого unitName, которое я добавил в @PersistenceContext.Пытается использовать Spring с JPA и JTA только с Spring Annotation

@Repository 
@Transactional 
public class UserController implements Serializable { 
    private static final long serialVersionUID = 4625223295588959802L; 

    @PersistenceContext(unitName="PerfJPASpring") 
    private EntityManager em; 

    @Transactional 
    public void addUser(User user) { 
     em.persist(user); 
    } 

    @Transactional 
    public void deleteAll() { 
     em.createNamedQuery("User.deleteAll").executeUpdate(); 
    } 

    @Transactional 
    public List<User> selectAllRecords() { 
     return em.createNamedQuery("User.findAll").getResultList(); 
    } 
} 

Другой вопрос, у меня есть, как я могу получить Spring использовать persistence.xml и не определить DataSource в LocalContainerEntityManagerFactoryBean. Я добавил источник данных на сервер приложений.

@Configuration 
@EnableTransactionManagement 
@EnableJpaRepositories(basePackageClasses=UserController.class) 
public class DatabaseConfig { 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
     EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter(); 
     vendorAdapter.setGenerateDdl(true); 
     vendorAdapter.setShowSql(false); 

     LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
     factory.setJpaVendorAdapter(vendorAdapter); 
     factory.setPackagesToScan("com.example.jpa.model"); 
     factory.setDataSource(dataSource()); 

     Properties jpaProps = new Properties(); 
     jpaProps.put("eclipselink.weaving", "false"); 
     factory.setJpaProperties(jpaProps); 
     return factory; 
    } 

    @Bean 
    public JpaTransactionManager transactionManager() throws SQLException { 
     JpaTransactionManager txManager = new JpaTransactionManager(); 
     txManager.setEntityManagerFactory(entityManagerFactory().getObject()); 
     return txManager; 
    } 

    public DataSource dataSource() { 
     try { 
      Context initCtx = new InitialContext(); 
      return (DataSource) initCtx.lookup("jdbc/userdb"); 
     } catch (Exception e) { 
      e.printStackTrace(); 
      throw new RuntimeException("Unable to lookup datasource", e); 
     } 
    }  
} 

Имя единицы измерения соответствует таковому в файле persistence.xml.

<?xml version="1.0" encoding="UTF-8"?> 
<persistence version="2.1" xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd"> 
    <persistence-unit name="PerfJPASpring" transaction-type="JTA"> 
     <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider> 
     <jta-data-source>jdbc/userdb</jta-data-source> 
     <class>com.example.jpa.model.User</class> 
    </persistence-unit> 
</persistence> 

И это ошибка, которую я получаю.

Uncaught init() exception created by servlet [DispatcherServlet] in application [PerfJPASpring]: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userController': Injection of persistence dependencies failed; nested exception is org.springframework.beans.factory.NoSuchBeanDefinitionException: No bean named 'PerfJPASpring' is defined 
    at org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor.postProcessPropertyValues(PersistenceAnnotationBeanPostProcessor.java:357) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.populateBean(AbstractAutowireCapableBeanFactory.java:1219) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:543) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:482) 
    at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306) 
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302) 
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197) 
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.preInstantiateSingletons(DefaultListableBeanFactory.java:751) 
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:839) 
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:538) 
    at org.springframework.web.servlet.FrameworkServlet.configureAndRefreshWebApplicationContext(FrameworkServlet.java:668) 
    at org.springframework.web.servlet.FrameworkServlet.initWebApplicationContext(FrameworkServlet.java:540) 
    at org.springframework.web.servlet.FrameworkServlet.initServletBean(FrameworkServlet.java:494) 
    at org.springframework.web.servlet.HttpServletBean.init(HttpServletBean.java:136) 
    at javax.servlet.GenericServlet.init(GenericServlet.java:244) 
    at [internal classes] 

Может мне точку в правильном направлении для Spring использовать UnitName и как я могу избежать указания источника данных в Db Config?

Спасибо.

ответ

0

Я нашел проблему. Во-первых, поскольку я использую JTA, я могу удалить @Transactional и удалить Datasource и заменить его на setPersistenceUnitName. Теперь он использует файл persistence.xml и JTA.

Служба:

@Repository 
public class UserController implements Serializable { 
    private static final long serialVersionUID = 4625223295588959802L; 

    @PersistenceContext(unitName="PerfJPASpring") 
    private EntityManager em; 

    public void addUser(User user) { 
     em.persist(user); 
    } 

    public void deleteAll() { 
     em.createNamedQuery("User.deleteAll").executeUpdate(); 
    } 

    public List<User> selectAllRecords() { 
     return em.createNamedQuery("User.findAll").getResultList(); 
    } 
} 

База данных конфигурации:

@Configuration 
@EnableJpaRepositories(basePackageClasses=UserController.class) 
public class DatabaseConfig { 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory() { 
     EclipseLinkJpaVendorAdapter vendorAdapter = new EclipseLinkJpaVendorAdapter(); 
     vendorAdapter.setGenerateDdl(true); 
     vendorAdapter.setShowSql(false); 

     LocalContainerEntityManagerFactoryBean factory = new LocalContainerEntityManagerFactoryBean(); 
     factory.setJpaVendorAdapter(vendorAdapter); 
     factory.setPackagesToScan("com.example.jpa.model"); 
     factory.setPersistenceUnitName("PerfJPASpring"); 

     Properties jpaProps = new Properties(); 
     jpaProps.put("eclipselink.weaving", "false"); 
     factory.setJpaProperties(jpaProps); 
     return factory; 
    } 

    @Bean 
    public JpaTransactionManager transactionManager() throws SQLException { 
     JpaTransactionManager txManager = new JpaTransactionManager(); 
     txManager.setEntityManagerFactory(entityManagerFactory().getObject()); 
     return txManager; 
    }  
}