1

アプリで奇妙なバグを見つけました。私はそれを単純化しました。それが再現できる方法です:

(私は DbUnit を使用してテーブルを作成し、HSQLDB をデータベースとして作成しましたが、それは実際には問題ではありません)

package test;

import java.io.IOException;
import java.io.Serializable;
import java.io.StringReader;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.Set;

import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.dbunit.DatabaseUnitException;
import org.dbunit.database.DatabaseConnection;
import org.dbunit.database.IDatabaseConnection;
import org.dbunit.dataset.IDataSet;
import org.dbunit.dataset.xml.FlatXmlDataSetBuilder;
import org.dbunit.operation.DatabaseOperation;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;
import org.springframework.orm.hibernate3.HibernateTemplate;

public class DatabaseBugReproduction {

    @Entity(name = "A")
    @Table(name = "a")
    public static class A {

        private int     id;
        private Set <B> bs;

        @Id
        public int getId() {
            return id;
        }

        @ManyToMany
        @JoinTable(
            name = "ab",
            joinColumns = @JoinColumn(name = "a_id"),
            inverseJoinColumns = @JoinColumn(name = "b_id")
        )
        public Set <B> getBs() {
            return bs;
        }

        void setId(int id) {
            this.id = id;
        }

        void setBs(Set <B> engines) {
            this.bs = engines;
        }
    }

    @Entity(name = "B")
    @Table(name = "b")
    public static class B {

        private int id;

        @Id
        public int getId() {
            return id;
        }

        void setId(int id) {
            this.id = id;
        }
    }

    private static SessionFactory getSessionFactory() throws SQLException, IOException, DatabaseUnitException {
        String driverClass = "org.hsqldb.jdbc.JDBCDriver";
        String jdbcUrl = "jdbc:hsqldb:mem:seoservertooltest";
        String dbUsername = "test";
        String dbPassword = "test";
        String dbDialect = "org.hibernate.dialect.HSQLDialect";
        Configuration config = new Configuration()//
        .setProperty("hibernate.connection.driver_class", driverClass)//
        .setProperty("hibernate.connection.url", jdbcUrl)//
        .setProperty("hibernate.connection.username", dbUsername)//
        .setProperty("hibernate.connection.password", dbPassword)//
        .setProperty("hibernate.dialect", dbDialect)//
        .setProperty("hibernate.hbm2ddl.auto", "create-drop")//
        .setProperty("hibernate.current_session_context_class", "thread")//
        .setProperty("hibernate.cache.use_query_cache", "true")//
        .setProperty("hibernate.cache.use_second_level_cache", "true")//
        .setProperty("hibernate.cache.region.factory_class", "net.sf.ehcache.hibernate.EhCacheRegionFactory")//
        .setProperty("hibernate.cache.region_prefix", "")//
        // .setProperty("hibernate.show_sql", "true")//
        // .setProperty("hibernate.format_sql", "true")//
        .addAnnotatedClass(A.class) //
        .addAnnotatedClass(B.class) //
        ;
        SessionFactory result = config.buildSessionFactory();
        try (Connection con = DriverManager.getConnection(jdbcUrl, dbUsername, dbPassword)) {
            con.createStatement().executeUpdate("SET DATABASE REFERENTIAL INTEGRITY FALSE;");
            String xml = "<?xml version='1.0' encoding='UTF-8'?>"//
                    + "<dataset>"//
                    + "<a id='1'/>"//
                    + "<b id='1'/>"//
                    + "<ab a_id='1' b_id='1' />"//
                    + "</dataset>";
            final IDatabaseConnection dbCon = new DatabaseConnection(con);
            try {
                final FlatXmlDataSetBuilder builder = new FlatXmlDataSetBuilder();
                final IDataSet dataSet = builder.build(new StringReader(xml));
                DatabaseOperation.CLEAN_INSERT.execute(dbCon, dataSet);
            } finally {
                dbCon.close();
            }
        }
        return result;
    }

    public static void main(String[] args) throws Exception {
        HibernateTemplate hibTemplate = new HibernateTemplate(getSessionFactory());
        hibTemplate.setCacheQueries(true);
        System.out.println(hibTemplate.find("select a.bs from A a"));
        System.out.println(hibTemplate.find("select a.bs from A a"));
    }
}

出力は次のとおりです。

[test.DatabaseBugReproduction$B@2942ce]
[null]

キャッシュの設定が間違っているようです。どこが間違っていて、どうすれば修正できますか?

使用済み:

  • JDK 1.7.0_01 x32 と x64 の両方
  • 休止状態 3.6.7
  • エーキャッシュ 2.5.0
  • 春 3.1.0
  • データベース: 少なくとも HSQLDB、H2、および MySQL で動作します
4

1 に答える 1