gpt4 book ai didi

hibernate - 非键列的@OneToOne 映射

转载 作者:行者123 更新时间:2023-12-05 06:22:41 24 4
gpt4 key购买 nike

我正致力于将 Hibernate 用于现有的遗留模式(我无法更新它)并且有一个奇怪的案例:

表用户:

  1. db_id 主键
  2. user_id(唯一约束)
  3. ...其他列

表地址

  1. db_id 公钥
  2. user_id(唯一约束)
  3. ...常用地址栏

它们是一对一的关系。我正在创建以下 @Entity 注释类。

class UserEntity {
@Id
@GeneratedValue
private UUID dbId;

private String userId;

@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "user_id", referencedColumnName = "user_id")
private AddressEntity address;
}
class AddressEntity {
@Id
@GeneratedValue
private UUID dbId;

private String userId;

@OneToOne
private UserEntity user;
}

Hibernate 认为这是一个重复的列定义,这是合理的。但是,由于在地址表中我没有 user_id 作为 FK 或 PK,我不确定如何将其传达给 Hibernate。我试图搜索类似但没有成功,所以任何建议将不胜感激。

最佳答案

已更新

可能有更好的方法来完成这个,比如使用 @NaturalId,但我无法让它与 Hibernate 5.2.12.Final 一起工作。

但是,@JoinFormula 可以拯救:

@Entity
@Table(name = "T_USER")
public class UserEntity implements Serializable
{
private static final long serialVersionUID = 1L;

@Id
@Type(type = "uuid-char")
@Column(name = "DB_ID", length = 36)
private UUID dbId;

@Column(name = "USER_ID", nullable = false, unique = true)
private String userId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinFormula("(select x.DB_ID from T_ADDRESS x where x.USER_ID=USER_ID)")
private AddressEntity address;

@Override
public String toString()
{
return String.format("%s: dbId=%s, userId=%s, address=%s",
getClass().getSimpleName(),
dbId,
userId,
address != null ? address.getDbId() : null);
}
}

@Entity
@Table(name = "T_ADDRESS")
public class AddressEntity implements Serializable
{
private static final long serialVersionUID = 1L;

@Id
@Type(type = "uuid-char")
@Column(name = "DB_ID", length = 36, nullable = false, unique = true)
private UUID dbId;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "USER_ID", referencedColumnName = "USER_ID")
private UserEntity user;

@Override
public String toString()
{
return String.format("%s: dbId=%s, user=%s",
getClass().getSimpleName(),
dbId,
user != null ? user.getDbId() : null);
}
}

使用 MySQL8 测试它:

CREATE TABLE `t_user` (
`DB_ID` varchar(36) NOT NULL,
`USER_ID` varchar(255) NOT NULL,
PRIMARY KEY (`DB_ID`),
UNIQUE KEY `UK_kvueux8cmkdekeqhrs7pumkwi` (`USER_ID`)
) ENGINE=InnoDB

CREATE TABLE `t_address` (
`DB_ID` varchar(36) NOT NULL,
`USER_ID` varchar(255) DEFAULT NULL,
PRIMARY KEY (`DB_ID`),
KEY `FK1s9gxk3we3yq11hjw5hp7ahp5` (`USER_ID`),
CONSTRAINT `FK1s9gxk3we3yq11hjw5hp7ahp5` FOREIGN KEY (`USER_ID`) REFERENCES `t_user` (`user_id`)
) ENGINE=InnoDB

使用这个又快又脏的启动器:

public class Main
{
public static void main(String[] args)
{
EntityManagerFactory emf = Persistence.createEntityManagerFactory("test_hibernate");
try
{
EntityManager em = emf.createEntityManager();
try
{
EntityTransaction transaction = em.getTransaction();
transaction.begin();

try
{
UserEntity user = new UserEntity();
user.setDbId(UUID.randomUUID());
user.setUserId("user_" + System.nanoTime());

em.persist(user);


AddressEntity address = new AddressEntity();
address.setDbId(UUID.randomUUID());

address.setUser(user);
user.setAddress(address);

em.persist(address);

transaction.commit();

System.out.println("persisted user: " + user);
System.out.println("persisted address: " + address);
}
catch(Exception e)
{
e.printStackTrace();
transaction.rollback();
}
}
finally
{
em.close();
}


EntityManager em2 = emf.createEntityManager();
try
{
List<UserEntity> userList = em2.createQuery("select x from UserEntity x", UserEntity.class).getResultList();
userList.forEach(x -> System.out.println("loaded user: " + x));

List<AddressEntity> addressList = em2.createQuery("select x from AddressEntity x", AddressEntity.class).getResultList();
addressList.forEach(x -> System.out.println("loaded address: " + x));
}
finally
{
em2.close();
}
}
finally
{
emf.close();
}

System.out.println("ok");
}
}

产生了这些结果:

persisted user: UserEntity: dbId=a22db668-eda0-4de1-83ae-98a7cd8738bd, userId=user_789235935853200, address=c17c0c28-603e-4961-90b0-16232346e47b
persisted address: AddressEntity: dbId=c17c0c28-603e-4961-90b0-16232346e47b, user=a22db668-eda0-4de1-83ae-98a7cd8738bd

loaded user: UserEntity: dbId=a22db668-eda0-4de1-83ae-98a7cd8738bd, userId=user_789235935853200, address=c17c0c28-603e-4961-90b0-16232346e47b
loaded address: AddressEntity: dbId=c17c0c28-603e-4961-90b0-16232346e47b, user=a22db668-eda0-4de1-83ae-98a7cd8738bd

关于hibernate - 非键列的@OneToOne 映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58986158/

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