0 0

JPA中在OneToMany中引用子类时出现的问题10

注:下面是采用hibernate的JPA实现时出现的问题.简单地描述一下: 当Client采用OnToMany关联到Sub1时,如果被关联方(Sub1)是Super的子类(单表策略),就无法通过client.getSub1()方法获取到正确的结果(最终获得的结果相当于client.getSuper(),即将全部super对象返回了,而不是返回对应的sub1对象).例举如下:
1.有继承体系如下:
Super
--Sub1
--Sub2
采用单表策略,即Sub1/Sub2存在一个单表中,用多态字段type区分.数据如下:
id   type  content
-------------------
-1   sub1  ...
-2   sub2  ...
-------------------
也就是sub1和sub2各对应一条记录

2.写了Sub1Dao/Sub2Dao对Sub1/Sub2进行增删改插,没有问题
3.有一个客户类Client,如下:
class Client {
    private Set<Sub1> sub1s;

    @OneToMany(...)
    public Set<Sub1> getSub1s() {
        return this.sub1s;
    }
}
4.另有一个ClientDao,并对其编写测试类,其中有这么一句:
Client client = clientDao.get("-1");
Assert.assertEquals(1, client.getSub1s().size());
结果报错,结果大致是:client.getSub1s().size()=2(期望为1,因为只有一条记录)
5.感觉是在表征表间关系时,对于继承体系,hibernate并不能取出正确的值.为此,打印出hibernate的取数sql,直接就是where id=-1,并不是期望中的,的确没有带where id=-1 and type='sub1'
6.这个结论是否正确?或是我处理有误?请指教.

问题补充:
晕,怎么楼主不能回贴啊...
呵呵,谢jones,不过我是采用的annotation,配置与你贴的是差不多的吧:
1)超类:
@Entity
@Table(name="person")
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name="type", discriminatorType=DiscriminatorType.STRING, length=50)
public class Person {}
2)子类:
@Entity
@DiscriminatorValue(value="SellerLeader")
public class SellerLeader extends Person {
/**
* 所属经销商
* @return 所属经销商
*/
@ManyToOne
@JoinColumn(name = "dealer_id", referencedColumnName = "id")
public Seller getSeller() {
return seller;
}
}
3)客户类:
@Entity
@Table(name="seller")
public class Seller extends Dealer {
/**
* 上级经销商
* @return
*/
@ManyToMany
@JoinTable(name="distributor_seller",
joinColumns=@JoinColumn(name="seller_id", referencedColumnName="id"),
inverseJoinColumns=@JoinColumn(name="distributor_id", referencedColumnName="id"))
public Set<Distributor> getDistributors() {
return distributors;
}
}
4)测试(由于是单表策略,person表共6条记录,其中SellerLeader有4条):
Seller seller = sellerDao.get(-2L);
Assert.assertEquals(4, seller.getLeaders().size());//注意:测试失败,告知说有6条而不是4条.
Assert.assertEquals(4, sellerLeaderDao.getAll().size());//测试成功,说有4条.
5)另外,所有的sellerLeaderDao方法都是成功的,也就是说多态本身是没有问题的,就是在ontomany关系中使用多态出问题了.
2008年11月08日 10:30

5个答案 按时间排序 按投票排序

0 0

楼上速度好快,很全面了,呵呵

2008年11月08日 11:50
0 0

hibernate中是可以区分不同子记录类别的,前提是得设置区分字段。
楼主用<discriminator column="type" type="xxx">设置子类的区分了吗?两个子类也需要设置discriminator-value值。

具体google吧

2008年11月08日 11:49
0 0

刚才给你查了一下JPA Annotation,应该这样写:

@Entity
@Inheritance(strategy=InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(
    name="判别字段",
    discriminatorType=DiscriminatorType.STRING
)


呵呵,试试吧

2008年11月08日 11:47
0 0

不好意思,打了很多错别字:
父类:

<discriminator column="type" type="string"/> 

    <subclass name="Sub1" discriminator -value="sub1">  
    ....................  
    </subclass>  
    <subclass name="Sub2" discriminator -value="sub2">  
    ....................  
    </subclass>  


呵呵

2008年11月08日 11:43
0 0

初步判断,是你的Annotation配置有问题,在Hibernate中我一般这么用:
在超类的配置文件中添加一个:
<discriminator column="type" type="string"/>

子类这样:

<subclass name="Sub1" duscrunubatir-value="sub1">
....................
</subclass>
<subclass name="Sub2" duscrunubatir-value="sub2">
....................
</subclass>


这样,当你抓取sub1子类的时候,生成的语句就是select ....from 你的超类 where type="sub1"
当你抓取sub2子类的时候,生成的语句就是select ....from 你的超类 where type="sub2"

2008年11月08日 11:41

相关推荐

Global site tag (gtag.js) - Google Analytics