欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

hibernate的Criteria的一个bug HibernateXMLSQL单元测试.net 

程序员文章站 2024-03-14 08:30:16
...

 

这个bug是在使用hibernate annotation过程中发现的,开始以为是hibenrate annotation的bug,后来又使用xml文件来配置,还是存在同样的问题。
问题场景:我需要使用省份与城市,他们的关系是:一个省有个多城市,很简单的OneToMany关系,在改变province中的cities的lazy特性时,遇到问题
由于我采用把所有的资源都是放在一个表中的策略,所有这里有一个基类Resource

基类

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net @Entity
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net @Inheritance(strategy 
= InheritanceType.SINGLE_TABLE)
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net @DiscriminatorColumn(name 
= "CATEGORY_ID", discriminatorType = DiscriminatorType.STRING)
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net @Table(name 
= "T_RESOURCE")
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
public class Resource implements Serializable ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
private String id;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
private String name;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
private ResourceCategory resourceCategory;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @Id
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @GenericGenerator(name 
= "generator", strategy = "uuid")
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @GeneratedValue(generator 
= "generator")
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @Column(name 
= "ID")
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public String getId() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
return id;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @Column(name 
= "NAME")
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public String getName() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
return name;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @ManyToOne(fetch 
= FetchType.LAZY)
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @JoinColumn(name 
= "CATEGORY_ID", updatable = false, insertable = false)
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public ResourceCategory getResourceCategory() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
return resourceCategory;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @Override
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public boolean equals(final Object other) ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
if (!(other instanceof Resource))
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net             
return false;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         Resource castOther 
= (Resource) other;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
return new EqualsBuilder().append(id, castOther.id).isEquals();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @Override
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public int hashCode() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
return new HashCodeBuilder().append(id).toHashCode();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 

Province子类

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net @Entity
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net @DiscriminatorValue(
"province")
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
public class Province extends Resource ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
private Set<City> cities = new HashSet<City>();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @OneToMany(cascade 
= CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "province")
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public Set<City> getCities() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
return cities;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 

 子类City

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net @Entity
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net @DiscriminatorValue(
"city")
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
public class City extends Resource ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
private Province province;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public City(String name, ResourceCategory resourceCategory) ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
super(name, resourceCategory);
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @ManyToOne
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     @JoinColumn(name 
= "PARENT_ID")
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public Province getProvince() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
return province;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net }

 hibernate.cfg.xml

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net <!-- 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     <mapping resource="ResourceCategory.hbm.xml" />
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     <mapping resource="Resource.hbm.xml" />
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
-->
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
<mapping class="ResourceCategory" />
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
<mapping class="Resource" />
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 

hibernate助手类

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net public class HibernateUtil ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
private static SessionFactory sessionFactory;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
static ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
// Configuration configuration = new Configuration();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
        AnnotationConfiguration configuration = new AnnotationConfiguration();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         configuration.configure();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         sessionFactory 
= configuration.buildSessionFactory();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public static SessionFactory getSessionFactory() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
return sessionFactory;
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public Session getSession() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
return getSessionFactory().openSession();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 

单元测试类

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net public class HibnerateTest extends TestCase ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public void testListProvinceByHQL() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         SessionFactory sessionFactory 
= HibernateUtil.getSessionFactory();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         Session session 
= sessionFactory.openSession();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         Transaction ctx 
= session.beginTransaction();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         Query query 
= session.createQuery("from Province");
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         List
<Province> provinces = query.list();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
for (Province province : provinces) ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net             System.out.println(province.getName());
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         ctx.commit();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
public void testListProvinceByCriteria() ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         SessionFactory sessionFactory 
= HibernateUtil.getSessionFactory();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         Session session 
= sessionFactory.openSession();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         Transaction ctx 
= session.beginTransaction();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         Criteria criteria 
= session.createCriteria(Province.class);
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         List
<Province> provinces = criteria.list();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
for (Province province : provinces) ...{
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net             System.out.println(province.getName());
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         ctx.commit();
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net }

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 

分别执行单元测试方法,他们输出的sql语句是一样的,但是输出的结果是不一样的。
select this_.ID as ID1_1_, this_.NAME as NAME1_1_, this_.COMMENTS as COMMENTS1_1_, this_.CATEGORY_ID as CATEGORY2_1_1_, cities2_.PARENT_ID as PARENT5_3_, cities2_.ID as ID3_, cities2_.ID as ID1_0_, cities2_.NAME as NAME1_0_, cities2_.COMMENTS as COMMENTS1_0_, cities2_.CATEGORY_ID as CATEGORY2_1_0_, cities2_.PARENT_ID as PARENT5_1_0_ from T_RESOURCE this_ left outer join T_RESOURCE cities2_ on this_.ID=cities2_.PARENT_ID where this_.CATEGORY_ID='province'
testListProvinceByHQL方式输出的是
上海
上海
上海
上海
江苏
江苏
江苏
江苏

testListProvinceByCriteria方式输出的是
上海
江苏


若把public Set<City> getCities()的映射改为
    @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "province")
    @Fetch(FetchMode.SELECT)
或者
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "province")
    @LazyCollection(LazyCollectionOption.FALSE)

则两个方法输出sql语句是一样的,且结果也一样
SQL:
select this_.ID as ID1_0_, this_.COMMENTS as COMMENTS1_0_, this_.NAME as NAME1_0_, this_.CATEGORY_ID as CATEGORY1_1_0_ from T_RESOURCE this_ where this_.CATEGORY_ID='province'
select cities0_.PARENT_ID as PARENT5_1_, cities0_.ID as ID1_, cities0_.ID as ID1_0_, cities0_.COMMENTS as COMMENTS1_0_, cities0_.NAME as NAME1_0_, cities0_.CATEGORY_ID as CATEGORY1_1_0_, cities0_.PARENT_ID as PARENT5_1_0_ from T_RESOURCE cities0_ where cities0_.PARENT_ID=?
select cities0_.PARENT_ID as PARENT5_1_, cities0_.ID as ID1_, cities0_.ID as ID1_0_, cities0_.COMMENTS as COMMENTS1_0_, cities0_.NAME as NAME1_0_, cities0_.CATEGORY_ID as CATEGORY1_1_0_, cities0_.PARENT_ID as PARENT5_1_0_ from T_RESOURCE cities0_ where cities0_.PARENT_ID=?
输出:
上海
江苏

从上面的现象可是看出,不论配置文件怎么变化,通过hql语句获得结果一直不变,而Criteria会变化,这就证明了Criteria是有bug的。
据此我得出结论:hibernate的Criteria在把关联的lazy属性设置为"false",且把fetch设置为join时,查找数据就存在bug

后来我使用xml配置文件的方式,也存在同样的问题,也证明了我的这个结论,

Resource.hbm.xml

hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net <?xml version="1.0"?>
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net "http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd"
>
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
<hibernate-mapping>
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net     
<class name="Resource"
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         table
="T_RESOURCE">
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
<id name="id" type="string">
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net             
<column name="ID" />
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
</id>
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
<discriminator column="CATEGORY_ID" type="string" />
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
<property name="name" type="string" column="NAME" />
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
<many-to-one name="resourceCategory" insert="false"
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net             update
="false"
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net             class
="ResourceCategory"
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net             column
="CATEGORY_ID" />
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net 
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net         
<subclass name="Province"
hibernate的Criteria的一个bug
            
    
    
        HibernateXMLSQL单元测试.net             discriminator-value
="province"