我现在开始学习jpa,我有一个关于owner和非owner的概念的问题,根据我读到的一篇文章,non-owner将是每个没有mappdBy的属性,但是当存在双向关系时,没有mappdBy表示法,我不确定是否有一个关系的所有者,我还注意到mappdBy选项只在它是@OneTo多而不是@ManyToOne时出现,也就是说,什么真正定义了关系的所有者以及它在实践中如何影响
每次运行应用程序时加载的初始数据
sql
insert into client (id, name) values (null, 'Marina');
insert into client (id, name) values (null, 'Joana');
insert into demand(id, name) values(null, "Banana");
insert into demand(id, name) values(null, "Apple");
insert into demand(id, name) values(null, "jabuticaba");
Demand.java
@Getter
@Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Entity
@Table(name = "demand")
public class Demand {
@Id
@EqualsAndHashCode.Include
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@ManyToOne
private Client client;
private String name;
}
Client.java
@Getter
@Setter
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
@Entity
@Table(name = "client")
public class Client {
@EqualsAndHashCode.Include
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String name;
@OneToMany
private List<Demand> demand;
}
Main.java
public class Main {
public static void main(String[] args) {
EntityManagerFactory entityManagerFactory =
Persistence.createEntityManagerFactory("unit");
EntityManager entityManager = entityManagerFactory.createEntityManager();
Client client = entityManager.find(Client.class, 1);
Demand demand1 = entityManager.find(Demand.class, 1);
Demand demand2 = entityManager.find(Demand.class, 2);
Demand demand3 = entityManager.find(Demand.class, 3);
entityManager.getTransaction().begin();
client.setDemand(Arrays.asList(demand1, demand2, demand3));
entityManager.getTransaction().commit();
client = entityManager.find(Client.class, 1);
System.out.println("Client name: " + client.getName() + " Demand name " +
client.getDemand().get(0).getName());
System.out.println("Client name: " + client.getName() + " Demand name " +
client.getDemand().get(1).getName());
}
}
我的最后一个问题是,谁是关系的所有者,因为我没有使用mappby?另一件事,我注意到它创建了一个中间表,当我不使用mappdBy时,如果有人能给我很多关于mappdBy如何工作的细节,我将非常感激。
你的假设是错误的。任何没有映射的字段都是所有者-映射表示“另一方”定义了关系,因此另一方拥有它。它仅在使用java双向关系映射数据库单向外键时使用。
在你
@ManyToOne
private Client client;
和
@OneToMany
private List<Demand> demand;
例如,您已经设置了两个彼此没有连接的独立关系。两者都将“拥有”它们的特定关系,并且表将需要两个单独的FK关系来映射;需求表将有一个FK来表示其客户端,而需求表将有另一个FK设置来表示客户端1: M到需求关系。
现在,如果您将它们定义为使用相同的外键,您将有(或应该有)警告和错误,说明您对同一外键有两个可写映射。如果对象模型不同步,双方都会尝试写入同一个外键,从而导致效率低下和问题。
当你不使用mappdBy
注释时,没有任何所有者。它只是两个表与独立表之间的关系。Hibernate不知道到底是哪一列,所以你必须向它显示哪个是哪个。