2个实体可以同时在它们之间有2个关系吗? (JPA)

时间:2014-08-26 11:07:19

标签: java jpa

例如,我有一个包含两个构造函数的帐户实体。

@Entity
public class DefaultAccount implements Account {

    @OneToOne(targetEntity = DefaultManager.class)
    private Manager manager;

    public DefaultAccount(String email, String password) {
       this.email = email;
       this.password = password;
    }

    public DefaultAccount(String email, String password, Manager manager) {
       this(email, password);
       this.manager = manager;
    }
    // Getters
}

第二个构造函数用于将帐户指定为经理。经理可以管理一组帐户。

@Entity
public class DefaultManager implements Manager {

        @OneToOne(targetEntity = DefaultAccount.class)
        private Account managerAccount;

        @OneToMany(fetch = FetchType.LAZY, mappedBy = "manager", targetEntity = DefaultAccount.class)
        private Set<Account> accountsToManage = new HashSet<Account>();

        public DefaultManager(Account managerAccount, Set<Account> accountsToManage) {
          this.managerAccount = managerAccount;
          this.accountsToManage.addAll(accountsToManage);
        }
        // Getters
}

上述关系是否有效?如果没有,那么使它运作的最佳选择是什么?

1 个答案:

答案 0 :(得分:1)

是的,它会起作用,你可以看到一个带有休眠here的SpringTest。

你需要一个没有参数的构造函数来使用JPA,这个构造函数不需要是public,它可以是protected

此外,您的实体需要使用@Id注释的字段。如果您的接口提供了@Id getter方法,则需要将注释(@OneToMany等)放在具体类的getters方法中。

如果执行测试,您将看到结果:

Hibernate: call next value for man_seq
Hibernate: insert into Test25504340$DefaultAccount (manager_id, password, email) values (?, ?, ?)
Hibernate: insert into Test25504340$DefaultAccount (manager_id, password, email) values (?, ?, ?)
Hibernate: insert into Test25504340$DefaultAccount (manager_id, password, email) values (?, ?, ?)
Hibernate: insert into Test25504340$DefaultManager (managerAccount_email, id) values (?, ?)
Hibernate: update Test25504340$DefaultAccount set manager_id=?, password=? where email=?

其中:

  1. 首先,获取插入管理器的序列(我将属性Long id添加到DefaultManager)。
  2. 它将添加引用Manager的三个帐户(帐户#manager - &gt; Manager#id)。
  3. 插入管理器
  4. 更新Manager#Account的引用,以Account为目标(Manager#manageAccount - &gt; Account#email)。
  5. 您可以更改调用的顺序(例如,persirst首先是管理器),结果将是具有相同最终结果的不同插入序列。