java - Spring boot session.enableFilter 导致 AssertionFailure : table not found

标签 java mysql maven spring-boot entitymanager

我正在尝试使用 Spring Boot 和EntityManager 来访问MySQL 数据库。但如果我使用 session.enableFilter 它会导致奇怪的异常。在互联网上尝试了很多搜索,但没有一个有帮助。

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;
    }
}

实体.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,结果是相同的。

如何解决这个问题?

最佳答案

基本上,DynamicFilterAliasGenerator存在一个问题,它不尊重hibernate.default_schema(它知道有表P_AENTITY,但作为它没有有关默认方案的信息,它无法将运行时表名称 myschema.P_AENTITY 与它所拥有的表名称进行比较)。

因此,如果您需要快速修复,只需从 hibernate 配置中删除 hibernate.default_schema 并在 jdbc.url 上中继即可。 所以不要有这样的东西

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

在 JDBC URL 中有这样的架构

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

关于java - Spring boot session.enableFilter 导致 AssertionFailure : table not found,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43631888/

相关文章:

java - 将公式放入 for 循环中

php - 使用 php 进行多个复选框和价格计算

java - Maven 告诉我我有一个 AMD64 处理器。我绝对使用英特尔处理器。这是怎么回事?

xml - JSF 2.1 + Tomcat 8 - 部署错误

maven - 如何修复: Host name 'repo1.maven.org' does not match the certificate subject provided

Java嵌套相关查询

java - Java 中 System.out.println() 的字符限制

java - Google Foobar 数字站

mysql - 如何从众多用户余额中获取最新的余额?

php - Codeigniter 分页从不同页面和不同员工的不同事件链接开始,而代码相同