2015-02-11 146 views
2

我正在使用spring-boot-starter-parent 1.2.0.RELEASE的Spring Boot项目。我试图通过spring SpringJtaSessionContext扩展来配置spring来使用Hibernate的JTASssionContext。春季数据JPA NPE in validateQuery与自定义entityManagerFactory和查询注释

在我的@Configuration类中,我返回了配置为LocalContainerEntityManagerFactoryBean的JTA。

@Configuration 
@EnableJpaRepositories(repositoryFactoryBeanClass = JpaRepositoryFactoryBean.class) 
@EntityScan(basePackageClasses = Event.class) 
public class JPAConfig { 

    @Autowired 
    private DataSource dataSource; 

    @Autowired 
    private JpaVendorAdapter jpaVendorAdapter; 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(){ 
     LocalContainerEntityManagerFactoryBean localContainerEntityManagerFactoryBean = new LocalContainerEntityManagerFactoryBean(); 
     localContainerEntityManagerFactoryBean.setJtaDataSource(dataSource ); 
     localContainerEntityManagerFactoryBean.setJpaVendorAdapter(jpaVendorAdapter); 
     HashMap<String, Object> properties = new HashMap<>(); 
     properties.put("hibernate.current_session_context_class", "jta"); 
     properties.put("javax.persistence.transactionType", "JTA"); 
     properties.put("hibernate.dialect", "org.hibernate.dialect.SQLServerDialect"); 
     properties.put("hibernate.format_sql", "true"); 
     properties.put("hibernate.ejb.naming_strategy", "org.springframework.boot.orm.jpa.hibernate.SpringNamingStrategy"); 
     localContainerEntityManagerFactoryBean.setJpaPropertyMap(properties); 
     return localContainerEntityManagerFactoryBean; 
    } 

} 

似乎一切都连接好,但我遇到了一个N​​PE的org.springframework.data.jpa.repository.query.SimpleJpaQuery

/** 
* Validates the given query for syntactical correctness. 
* 
* @param query 
* @param em 
*/ 
private final void validateQuery(String query, String errorMessage) { 

    if (getQueryMethod().isProcedureQuery()) { 
     return; 
    } 

    EntityManager validatingEm = null; 

    try { 
     validatingEm = getEntityManager().getEntityManagerFactory().createEntityManager(); 
.... 

getEntityManager().getEntityManagerFactory().createEntityManager();导致这似乎NPE的通话将被未来内而外的createEntityManager()

提供的getEntityManager()类似乎是我在JPAConfig中定义的LocalContainerEntityManagerFactoryBean。提供的EntityManagerFactory似乎是org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean。看起来像createEntityManager()里面的东西是空的。

这将导致以下堆栈跟踪

Caused by: java.lang.IllegalArgumentException: Validation failed for query for method public abstract com.vnomicscorp.dw.model.Event com.vnomicscorp.dw.webservice.repo.EventRepository.findByCompositeKey(com.vnomicscorp.dw.model.Vehicle,com.vnomicscorp.dw.model.EventType,long)! 
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:87) 
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.<init>(SimpleJpaQuery.java:57) 
    at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromMethodWithQueryString(JpaQueryFactory.java:70) 
    at org.springframework.data.jpa.repository.query.JpaQueryFactory.fromQueryAnnotation(JpaQueryFactory.java:51) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$DeclaredQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:137) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:202) 
    at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:80) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:357) 
    at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:192) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.initAndReturn(RepositoryFactoryBeanSupport.java:239) 
    at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.afterPropertiesSet(RepositoryFactoryBeanSupport.java:225) 
    at org.springframework.data.jpa.repository.support.JpaRepositoryFactoryBean.afterPropertiesSet(JpaRepositoryFactoryBean.java:92) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1625) 
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1562) 
    ... 240 more 
Caused by: java.lang.NullPointerException 
    at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.getStatus(JtaStatusHelper.java:76) 
    at org.hibernate.engine.transaction.internal.jta.JtaStatusHelper.isActive(JtaStatusHelper.java:118) 
    at org.hibernate.engine.transaction.internal.jta.CMTTransaction.join(CMTTransaction.java:149) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.joinTransaction(AbstractEntityManagerImpl.java:1602) 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.postInit(AbstractEntityManagerImpl.java:210) 
    at org.hibernate.jpa.internal.EntityManagerImpl.<init>(EntityManagerImpl.java:91) 
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.internalCreateEntityManager(EntityManagerFactoryImpl.java:345) 
    at org.hibernate.jpa.internal.EntityManagerFactoryImpl.createEntityManager(EntityManagerFactoryImpl.java:313) 
    at sun.reflect.GeneratedMethodAccessor48.invoke(Unknown Source) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:483) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.invokeProxyMethod(AbstractEntityManagerFactoryBean.java:388) 
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean$ManagedEntityManagerFactoryInvocationHandler.invoke(AbstractEntityManagerFactoryBean.java:541) 
    at com.sun.proxy.$Proxy76.createEntityManager(Unknown Source) 
    at org.springframework.data.jpa.repository.query.SimpleJpaQuery.validateQuery(SimpleJpaQuery.java:80) 
    ... 253 more 

将造成线以这种方法反映指向调用

Object retVal = method.invoke(this.nativeEntityManagerFactory, args); 

我还要补充,我使用Spring数据休息和有RepositoryRestMvcConfiguration类也是如此。

@Configuration 
public class RestRepoConfig extends RepositoryRestMvcConfiguration { 

    @Override 
    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) { 
     config.exposeIdsFor(Employee.class, Vehicle.class, Customer.class, VehicleMake.class, VehicleModel.class, Event.class); 
    } 
} 

在尝试使用添加的方法验证PagingAndSortingRepository时,正在抛出NPE。

public interface EventRepository extends PagingAndSortingRepository<Event, Long> { 

    @Query("SELECT e FROM Event AS e WHERE e.vehicle = :vehicle AND e.startTime <= :endTime AND e.endTime >= :startTime") 
    public Iterable<Event> findByTimeperiod(@Param("vehicle") Vehicle vehicle, 
             @Param("startTime") long startTime, 
             @Param("endTime") long endTime); 

    @Query("SELECT e FROM Event AS e WHERE e.vehicle = :vehicle AND e.eventType = :eventType AND e.startTime = :startTime") 
    public Event findByCompositeKey(@Param("vehicle") Vehicle vehicle, 
           @Param("eventType") EventType eventType, 
           @Param("startTime") long startTime); 
} 
+1

你能分享所有重现问题所需的代码吗?上面的东西适用于我(一旦我填补了空白)。 – 2015-02-11 17:36:14

+0

@AndyWilkinson我添加了似乎在NPE根部的PagingAndSortingRepository。 – francis 2015-02-11 17:50:40

+1

请提供更多validateQuery方法的代码。我已经有了一个想法,但是......另外相关的Stacktrace将大大帮助我们检查你的假设与现有信息。 – Vogel612 2015-02-12 10:05:42

回答

1

Andy Wilkinson的评论很有用。由于配置问题,问题是空的事务管理器。

+0

虽然此评论可能已解决你的问题,这是回避主要问题。在某些情况下,配置持久性的程序化'LocalContainerEntityManagerFactoryBean'路由是必要的。 – 2016-03-30 12:42:31