2017-04-26 22 views
0

我試圖使用spring啓動和entitymanager來訪問mysql數據庫。但如果我使用session.enableFilter它會導致奇怪的異常。在互聯網上嘗試了很多搜索,但沒有一個幫助。春季啓動session.enableFilter導致AssertionFailure:表未找到

DataSourceContext.java

@Configuration 
@EnableTransactionManagement 
public class DataSourceContext { 
    public final static String DB_PREFIX = "P_"; 

    @Autowired 
    Environment env; 

    @Bean 
    @Qualifier("dataSource") 
    public DataSource dataSource(Properties hibernateProperties) { 
     DriverManagerDataSource ds = new DriverManagerDataSource(); 
     ds.setUsername(env.getProperty("jdbc.username")); 
     ds.setPassword(env.getProperty("jdbc.password")); 
     ds.setUrl(env.getProperty("jdbc.url")); 
     ds.setDriverClassName(env.getProperty("jdbc.driverClassName")); 
     ds.setConnectionProperties(hibernateProperties); 
     return ds; 
    } 

    @Bean 
    public LocalContainerEntityManagerFactoryBean entityManagerFactory(@Qualifier("dataSource") DataSource dataSource, Properties hibernateProperties) { 
     HibernateJpaVendorAdapter vendorAdapter = new HibernateJpaVendorAdapter(); 
     vendorAdapter.setGenerateDdl(true); 

     final LocalContainerEntityManagerFactoryBean em = new LocalContainerEntityManagerFactoryBean(); 
     em.setDataSource(dataSource); 
     em.setPackagesToScan("com.example.model"); 
     em.setJpaVendorAdapter(vendorAdapter); 
     em.setJpaProperties(hibernateProperties); 
     em.setPersistenceUnitName("persistanceUnit"); 
     em.setPersistenceProviderClass(HibernatePersistenceProvider.class); 
     em.afterPropertiesSet(); 

     return em; 
    } 

    @Bean 
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) { 
     JpaTransactionManager tm = new JpaTransactionManager(); 
     tm.setEntityManagerFactory(entityManagerFactory); 
     return tm; 
    } 

    @Bean 
    public Properties hibernateProperties() { 
     final Properties properties = new Properties(); 

     properties.put("hibernate.dialect", env.getProperty("hibernate.dialect")); 
     properties.put("hibernate.show_sql", env.getProperty("hibernate.show_sql")); 
     properties.put("hibernate.format_sql", env.getProperty("hibernate.format_sql")); 
     properties.put("hibernate.hbm2ddl.auto", env.getProperty("hibernate.hbm2ddl.auto")); 
     properties.put("hibernate.default_schema", env.getProperty("hibernate.default_schema")); 

     return properties; 
    } 
} 

Aentity.java

@Entity 
@Table(name = DataSourceContext.DB_PREFIX + "AENTITY") 
@FilterDef(name = "statusFilter", defaultCondition = "STATUS = :status ", parameters = @ParamDef(name = "status", type = "string")) 
@Filters({@Filter(name = "statusFilter", condition = "STATUS = :status")}) 
public class Aentity implements Serializable { 
    private Long id; 
    private EntityStatus status; 
    private Date createdDate; 
    private Date updatedDate; 
    private Date deletedDate; 
    private Long version; 

    // getters and setter with column annotations. 
} 

Adao.java

@Transactional(rollbackFor = Exception.class) 
@Repository 
public class Adao { 

    @PersistenceContext 
    protected EntityManager em; 

    public EntityManager getEm() { 
     /* exception lines */ 
     em.unwrap(Session.class) 
      .enableFilter("statusFilter") 
      .setParameter("status", EntityStatus.ACTIVE.name()); 

     return em; 
    } 

    public List<Aentity> findAll() { 
     List resultList = getEm().createQuery("select distinct aentity from Aentity aentity") 
       .getResultList(); 

     return resultList; 
    } 
} 

的pom.xml

 <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-aop</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-web</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-data-jpa</artifactId> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework.boot</groupId> 
      <artifactId>spring-boot-starter-test</artifactId> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>mysql</groupId> 
      <artifactId>mysql-connector-java</artifactId> 
     </dependency> 

原木;

----unrelated logs---- 
2017-04-26 13:32:36.145 INFO 60417 --- [   main] o.h.h.i.QueryTranslatorFactoryInitiator : HHH000397: Using ASTQueryTranslatorFactory 
2017-04-26 13:32:36.187 ERROR 60417 --- [   main] org.hibernate.AssertionFailure   : HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: Table myschema.P_AENTITY not found 
----unrelated logs---- 

----some logs---- 
Caused by: org.hibernate.AssertionFailure: Table myschema.P_AENTITY not found 
    at org.hibernate.persister.entity.AbstractEntityPersister.getTableId(AbstractEntityPersister.java:5181) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.internal.DynamicFilterAliasGenerator.getAlias(DynamicFilterAliasGenerator.java:31) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.internal.FilterHelper.render(FilterHelper.java:109) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.internal.FilterHelper.render(FilterHelper.java:96) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.persister.entity.AbstractEntityPersister.filterFragment(AbstractEntityPersister.java:3587) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.engine.internal.JoinSequence.toJoinFragment(JoinSequence.java:175) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.hql.internal.ast.util.JoinProcessor.addJoinNodes(JoinProcessor.java:147) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.hql.internal.ast.util.JoinProcessor.processJoins(JoinProcessor.java:141) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.hql.internal.ast.HqlSqlWalker.processQuery(HqlSqlWalker.java:694) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:673) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:309) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.hql.internal.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:257) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:262) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:190) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.hql.internal.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:142) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:115) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.engine.query.spi.HQLQueryPlan.<init>(HQLQueryPlan.java:76) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.engine.query.spi.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:150) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.internal.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:302) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.internal.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:240) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.internal.SessionImpl.createQuery(SessionImpl.java:1894) ~[hibernate-core-5.0.12.Final.jar:5.0.12.Final] 
    at org.hibernate.jpa.spi.AbstractEntityManagerImpl.createQuery(AbstractEntityManagerImpl.java:291) ~[hibernate-entitymanager-5.0.12.Final.jar:5.0.12.Final] 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121] 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121] 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_121] 
    at java.lang.reflect.Method.invoke(Method.java:498) ~[na:1.8.0_121] 
    at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:298) ~[spring-orm-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
    at com.sun.proxy.$Proxy80.createQuery(Unknown Source) ~[na:na] 
    at com.example.dao.Adao.findAll(Adao.java:27) ~[classes/:na] 
    at com.example.dao.Adao$$FastClassBySpringCGLIB$$c40f7d5e.invoke(<generated>) ~[classes/:na] 
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:204) ~[spring-core-4.3.8.RELEASE.jar:4.3.8.RELEASE] 
----some logs---- 

如果我刪除Adao.java類中的啓用過濾器,那麼它工作正常。

另一種情況是,如果我使用SessionFactory而不是entitymanager,結果是一樣的。

我該如何解決這個問題?

回答

1

基本上沒有與DynamicFilterAliasGenerator的問題,它不尊重hibernate.default_schema(它知道有表P_AENTITY但因爲它在默認方案沒有信息就無法運行表名myschema.P_AENTITY與它有一個比較)。

所以,如果您需要快速修復,只需從您的hibernate.default_schema刪除休眠配置和繼電器jdbc.url。 所以不是有這樣的

properties.put("hibernate.default_schema", "myschema"); 

東西有這樣

DriverManagerDataSource ds = new DriverManagerDataSource(); 
.... 
ds.setUrl("jdbc:mysql://localhost:3306/myschema"); 
.... 
+0

感謝您的回答,這是工作。如果它很快修復,那麼這種情況的真正解決方案是什麼? – rcpayan

1

你可以檢查的杉杉在JDBC URL模式不Hibernate配置具有以下屬性:

hibernate.dialect=org.hibernate.dialect.MySQLDialect //you should use mysql dialect from pom I see that you use mysql 
#hibernate.default_schema=myCustomName    //commented out in case you want use default schema, else you can use this property to create your custom schema 
hibernate.show_sql=true        //this will help so see what queries are executed 
hibernate.format_sql=true        //this will print formatted sql 
hibernate.hbm2ddl.auto=create       //this will generate database tables if they don't exist in DB, also you can change to "update" this property then database will get updates. 

第二件事我懷疑可能有引號的問題,他們是在JPA風格,但沒有在冬眠嘗試(是否有理由在狀態作爲大寫在過濾器?):

@Entity 
@Table(name = DataSourceContext.DB_PREFIX + "AENTITY") 
@FilterDef(name = "statusFilter", defaultCondition = "`status` = :status ", parameters = @ParamDef(name = "status", type = "string")) 
@Filter(name = "statusFilter", condition = "`status` = :status") 
public class Aentity implements Serializable { 
    private Long id; 
    private EntityStatus status; 
    private Date createdDate; 
    private Date updatedDate; 
    private Date deletedDate; 
    private Long version; 

    // getters and setter with column annotations. 
}