gpt4 book ai didi

java - 具有共享主键的两个表之间的 OneToOne

转载 作者:搜寻专家 更新时间:2023-10-30 21:00:24 28 4
gpt4 key购买 nike

我正在尝试使用 JPA/Hibernate 设置下表:

User:

userid - PK
name

Validation:

userid - PK, FK(user)
code

可能有很多用户,每个用户可能最多有一个验证码,也可能没有。

这是我的类(class):

public class User 
{
@Id
@Column(name = "userid")
@GeneratedValue(strategy = GenerationType.IDENTITY)
protected Long userId;

@Column(name = "name", length = 50, unique = true, nullable = false)
protected String name;

...
}

public class Validation
{
@Id
@Column(name = "userid")
protected Long userId;

@OneToOne(cascade = CascadeType.ALL)
@PrimaryKeyJoinColumn(name = "userid", referencedColumnName = "userid")
protected User user;

@Column(name = "code", length = 10, unique = true, nullable = false)
protected String code;

...

public void setUser(User user)
{
this.user = user;
this.userId = user.getUserId();
}

...
}

我创建了一个用户,然后尝试使用以下代码添加验证码:

public void addValidationCode(Long userId)
{
EntityManager em = createEntityManager();
EntityTransaction tx = em.getTransaction();

try
{
tx.begin();

// Fetch the user
User user = retrieveUserByID(userId);

Validation validation = new Validation();
validation.setUser(user);
em.persist(validation);
tx.commit();
}
...
}

当我尝试运行它时,我得到一个 org.hibernate.PersistentObjectException: detached entity passed to persist: User

我还尝试在我的验证类中使用以下代码:

public void setUserId(Long userId)
{
this.userId = userId;
}

当我创建验证码时,我只是这样做:

Validation validation = new Validation();
validation.setUserId(userId);
em.persist(validation);
tx.commit();

但是由于 User 为 null 我得到 org.hibernate.PropertyValueException: not-null property references a null or transient value: User.code

对于如何最好地解决此问题的任何帮助,我们将不胜感激!

最佳答案

我已经能够以纯 JPA 2.0 方式解决“具有共享主键的两个表之间的一对一”问题(感谢 SOF 上的许多现有线程)。事实上,在 JPA 中有两种方法可以处理这个问题。我使用 eclipselink 作为 JPA 提供程序,使用 MySql 作为数据库。再次强调这里没有使用专有的 eclipselink 类。

  1. 第一种方法是在父实体的标识符字段上使用自动生成类型策略。

    • 父实体必须包含 OneToOne 关系中的子实体类型成员(级联类型 PERSIST 和 mappedBy = 子实体的父实体类型成员)

      @Entity
      @Table(name = "USER_LOGIN")
      public class UserLogin implements Serializable {
      @Id
      @GeneratedValue(strategy = GenerationType.AUTO)
      @Column(name="USER_ID")
      private Integer userId;

      @OneToOne(cascade = CascadeType.PERSIST, mappedBy = "userLogin")
      private UserDetail userDetail;
      // getters & setters
      }
    • 子实体不得包含标识符字段。它必须包含具有 Id、OneToOne 和 JoinColumn 注释的父实体类型的成员。 JoinColumn必须指定DB表的ID字段名。

      @Entity
      @Table(name = "USER_DETAIL")
      public class UserDetail implements Serializable {
      @Id
      @OneToOne
      @JoinColumn(name="USER_ID")
      private UserLogin userLogin;
      // getters & setters
      }
    • 上述方法在内部使用名为 SEQUENCE 的默认数据库表将值分配给标识符字段。如果不存在,则需要按如下方式创建该表。

      DROP TABLE TEST.SEQUENCE ;
      CREATE TABLE TEST.SEQUENCE (SEQ_NAME VARCHAR(50), SEQ_COUNT DECIMAL(15));
      INSERT INTO TEST.SEQUENCE(SEQ_NAME, SEQ_COUNT) values ('SEQ_GEN', 0);
  2. 第二种方法是在父实体的标识符字段上使用自定义的 TABLE 生成类型策略和 TableGenerator 注释。

    • 除了标识符字段的上述更改外,父实体中的其他所有内容都保持不变。

      @Entity
      @Table(name = "USER_LOGIN")
      public class UserLogin implements Serializable {
      @Id
      @TableGenerator(name="tablegenerator", table = "APP_SEQ_STORE", pkColumnName = "APP_SEQ_NAME", pkColumnValue = "USER_LOGIN.USER_ID", valueColumnName = "APP_SEQ_VALUE", initialValue = 1, allocationSize = 1 )
      @GeneratedValue(strategy = GenerationType.TABLE, generator = "tablegenerator")
      @Column(name="USER_ID")
      private Integer userId;

      @OneToOne(cascade = CascadeType.PERSIST, mappedBy = "userLogin")
      private UserDetail userDetail;
      // getters & setters
      }
    • 子实体没有变化。它与第一种方法相同。

    • 此表生成器方法在内部使用数据库表 APP_SEQ_STORE 将值分配给标识符字段。该表需要按如下方式创建。

      DROP TABLE TEST.APP_SEQ_STORE;
      CREATE TABLE TEST.APP_SEQ_STORE
      (
      APP_SEQ_NAME VARCHAR(255) NOT NULL,
      APP_SEQ_VALUE BIGINT NOT NULL,
      PRIMARY KEY(APP_SEQ_NAME)
      );
      INSERT INTO TEST.APP_SEQ_STORE VALUES ('USER_LOGIN.USER_ID', 0);

关于java - 具有共享主键的两个表之间的 OneToOne,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5805306/

28 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com