2011-03-27 69 views
0

我有以下类别:JPA:单向一对多问题

class A{ 
    @OneToOne(cascade=CascadeType.ALL) 
    private B b; 
} 

class C{ 
    @ManyToOne 
    private A a;  
} 

class B{ 
    @OneToOne 
    private A a; 

    @MapKey(name = "name") 
    @OneToMany(cascade = CascadeType.ALL, ...) 
    @JoinColumn(...) 
    private Map<String C> cs; 
} 

如何做我必须指定在B.cs映射加入其中B.a == C.A?

这可能吗?或者我必须将C.a属性更改为C.b? (我更愿意保持原样,因为实体B只是一个辅助类。) 我也尝试将B更改为@Embeddable,但Map不支持嵌入。

回答

0

我想你可以从延伸A.

B如果这不适合你,也许你可以添加一个短暂的财产是指A的ID,

@Transient 
Integer getId1() { 
    return a.getId(); 
} 

和将C使用 id1而不是B的主键。

编辑:这不起作用。

+0

“derive”是什么意思?遗产?。这是一个组合,其中A有更多的属性,B有更多的属性。一个关系(继承)在这里是错误的。 – Puce 2011-03-27 18:12:11

+0

我的意思是'延伸'在这里。也许你是对的。在这种情况下,我个人将创建另一个基类_A,并使A和B扩展_A。 – 2011-03-27 23:55:49

1

JPA要求所有关系都由Id(外键引用主键)。 因此,您需要将@ManyToOne从C添加到B. 或者,确保B的Id是A的外键(将@OneToOne上的@Id从B添加到A并删除A的另一个@Id)。 如果B是A的一个子类而不是OneToOne,这也可以。

如果您使用的是EclipseLink,则可以为关系定义更复杂的标准。您需要使用DescriptorCustomizer和OneToManyMapping API来定义OneToMany的外键。

+0

外键(在C中)引用主键(A),它只是不是B的主键。我认为我很难与JPA不允许将B定义为@Embeddable。但是你说我只有这3个选择:@ManyToOne从C到B,@ID从@到@OneToOne从B到A(这是一个很好的做法?)或EclipseLink特定的映射(离开JPA标准),对不对? – Puce 2011-03-29 17:20:39