JPA注释和mappedBy

3
我是一名Java应用程序员,正在使用JPA与数据库进行交互,我有两个重要问题:
  1. 我想在两个类之间建立双向链接,因为我需要从两个方向访问数据。我们以A和B两个类为例,它们之间的关系是A *-1 B(就像UML图中的一样,A有一个唯一的B,而B有多个A..)。

在A类中:

@ManyToOne
private B attribute; 

在B中
@OneToMany
private List<A> list;

这样是否足以形成双向链接?还是必须使用mappedBy?

  1. 这就引出了我的第二个问题,如果在错误的一侧放置mappedBy会对性能产生影响甚至更糟吗?(数据未持久化)?例如,在基数为1-*的情况下,我们别无选择,mappedBy应该在OneToMany的一侧,在这种情况下:

B中

@OneToMany(mappedBy = "attribute")
private List<A> list;

考虑到我不会创建B类,而是创建一个列表并分配对象,我将不会在B侧做任何事情。我只需重复创建A类,并每次为其分配一个B对象,这样我可能会有几个A类具有相同的受影响的B对象,并且我希望B自动更新此链接及其A列表。

3个回答

2
中译英:
“那是足够建立双向链接了吗?还是必须使用 mappedBy?”
“对于双向关系,这是强制性的。”
“这就引出了我的第二个问题,如果在错误的一侧放置了 mappedBy,它会影响性能甚至更糟吗?(数据不会被持久化)?”
“更糟——它不会起作用,但它不会是静默失败,你会看到异常。”
“话虽如此,这很容易理解。 它与 @OneToMany 一起使用。”
这篇文章可能会帮助您更好地理解。”

1
非常感谢! 1- 如果我不指定mappedBy,它会工作,但是两个实体之间将没有任何链接,对吗? 2- mappedBy放置在错误的一侧只能在OneToMany或ManyToOne的情况下发生,因为对于1-1和*-*,我们可以选择哪个是所有者的一侧,对吗? 3- 如果mappedBy放错了位置,当我尝试向数据库添加数据时,我会遇到异常,而不是在开始时(仅编写模型),对吗?非常感谢 - TER
是的,你对这三个问题都正确。只是为了详细说明第一点:是的,你关于两者之间的关联是正确的。这被称为“双向”关系,在深入学习JPA时你会经常遇到这个术语。 - Shahzeb

1
  • 应该在没有外键的实体(很可能是B)中添加 mappedBy
  • 如果 mappedBy 在错误的一侧,您将会看到一个异常。

1
这足以建立双向链接吗?还是必须使用mappedBy属性?
不完全正确。对于反向的双向多对一关系,即没有外键且始终为多对一关系中的“一”侧的那一侧,您确实需要MappedBy属性。您还需要在关系的“多”侧上提供joincolumn信息。
因此,总之:
“多对一”侧 - 关系的拥有方 - 需要在此侧指定@JoinColumn信息。这需要在单向和双向关系中都指定。
“一对多”侧 - 反向侧 - 此侧需要mappedBy属性。如果关系是双向的,则需要指定此属性。
@Entity
public class A ……..
//Owning side of the relationship with the @JoinColumn annotation.
    @ManyToOne
    // Assume TABLEPK column holds PK of B's table
    @JoinColumn (name = "TABLEBPK")
    private B attribute;


@Entity
public class B ……

//Inverse side of the relationship with the MappedBy attribute.
    @OneToMany(MappedBy = “attribute”)
    private List<A> list;

这让我们来到我的第二个问题,如果mappedBy放在错误的一侧,它只会影响性能还是更糟?它将无法工作。只需将其放在关系的反向一侧即可。
知道我不会创建类B,并且创建一个列表并分配对象,我在B方面什么都不做。我只是重复创建类A,并且每次为其分配一个B对象,因此可能有多个类A具有相同的受影响对象B,我希望B自动更新此链接及其A列表。在这种情况下,您创建一个类A,其中属性字段填充了B的实例。现在,当您持久化A-一个新实例时,它将包含一个B实例,该实例可能是新的也可能不是新的。我们希望JPA持久化A,然后沿着关系导航并持久化B。如果B已经存在于持久化上下文中,则忽略它。添加CascadeType.PERSIST将实现此目的。
@Entity
public class A ……..
//Owning side of the relationship with the @JoinColumn annotation.
    @ManyToOne(cascade = CascadeType.PERSIST)
    @JoinColumn (name = "TABLEBPK")
    private B attribute;

这些人在这个领域写得非常好......《Java™持久化API掌握Pro JPA 2》由Mike Keith和Merrick Schnicariol撰写。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接