在具有条件的左连接条件之后,如何防止Hibernate加载一对一字段?

时间:2015-03-19 16:31:37

标签: java hibernate

我有以下数据库表:

Cats
ParentID | Name
-----------------
1        | Mittins
2        | Cuddles
3        | Spot

Kittens
ID | ParentID | Color
---------------------
1  | 1        | Red
2  | 1        | Yellow
3  | 1        | Blue
4  | 2        | Red
5  | 2        | Blue
6  | 3        | Red
7  | 3        | Yellow
8  | 3        | Blue

以下Mapping类:

class Cat
{
   @Id
   @Column(name="ParentID", nullable = false)
   public Integer parentID;

   @Column(name="Name", nullable = false)
   public String name;

   @OneToOne
   @JoinColumn(name="parentID")
   @NotFound(action=NotFoundAction.IGNORE)
   public Kitten kitten;
}

class Kitten
{
   @Id
   @Column(name="ID", nullable = false)
   public Integer id;

   @Column(name="ParentID", nullable = false)
   public Integer parentID;

   @Column(name="Color", nullable = false)
   public String color;
}

我希望cat加入指定颜色的kitten。保证每只猫只有一只一只特定颜色的小猫。然后,该实例的映射将是一对一的。

Criteria crit = sessionFactory.getCurrentSession().createCriteria(Cat.class, "cat");
crit.createCriteria("cat.kitten", "kitten", Criteria.LEFT_JOIN, Restrictions.eq("kitten.color", "Red"));

crit.list();

这将返回3个Cat对象,每个对象都填充了" Red"小猫的对象。 Hibernate一次性得到这个。在获取期间填充Kitten数据,并且不执行子查询以获取小猫数据。

但是,例如,如果我搜索"黄色"小猫,我仍然想要我得到的3个猫对象。但是我希望null为没有黄色小猫的猫的小猫场(猫#2)。

相反,hibernate所做的是尝试通过parentID上的另一个子查询加载cat 2的所有小猫。

我不希望它这样做,因为映射不知道我的原始左连接标准仅限于"黄色"小猫。这当然会导致"找到具有给定标识符的多个行"错误。

当执行原始标准时,hibernate应该知道"小猫"部分查询返回NULL。是否有可能让Hibernate设置该字段null而不是稍后会尝试第二次错误查询加载小猫对象的代理?

1 个答案:

答案 0 :(得分:0)

首先,它不是oneToOne而是OneToMany,因为Cat可以拥有许多小猫。所以你应该使用Map来映射到OneToMany,其中颜色是关键,值是正确的小猫。

@OneToMany
@MapKey(name="color") 
@JoinColumn(name="parentID")
Map<String,Kitten> kittens;

您的java对象应该代表db模型,而不是可能的查询结果。 你仍然可以查询有特殊小猫的猫。