提问者:小点点

关于JPA所有者和非所有者的问题@OneTo很多


我现在开始学习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如何工作的细节,我将非常感激。


共2个答案

匿名用户

你的假设是错误的。任何没有映射的字段都是所有者-映射表示“另一方”定义了关系,因此另一方拥有它。它仅在使用java双向关系映射数据库单向外键时使用。

在你

@ManyToOne
private Client client;

@OneToMany
private List<Demand> demand;

例如,您已经设置了两个彼此没有连接的独立关系。两者都将“拥有”它们的特定关系,并且表将需要两个单独的FK关系来映射;需求表将有一个FK来表示其客户端,而需求表将有另一个FK设置来表示客户端1: M到需求关系。

现在,如果您将它们定义为使用相同的外键,您将有(或应该有)警告和错误,说明您对同一外键有两个可写映射。如果对象模型不同步,双方都会尝试写入同一个外键,从而导致效率低下和问题。

匿名用户

当你不使用mappdBy注释时,没有任何所有者。它只是两个表与独立表之间的关系。Hibernate不知道到底是哪一列,所以你必须向它显示哪个是哪个。