gpt4 book ai didi

java - Hibernate OneToOne 之间具有惰性行为的 PK

转载 作者:行者123 更新时间:2023-12-01 17:29:59 25 4
gpt4 key购买 nike

我正在尝试使用 Hibernate 5.3.13.Final 并在 Wildfly 18 下使用注释来实现一个名为 MyEntity 的实体以及另一个名为 MyEntityInfo 的实体。

这个想法是让 MyEntity 存储一些常见请求的字段,而 MyEntityInfo 存储一些很少请求的字段。两者共享相同的主键,称为SID(长整型),并且从Info的SID到Entity的SID存在一个FK。可能存在没有信息的实体。

通常您不需要附加信息。例如,当我像这样查询实体时,我不希望获取信息实体:

MyEntityImpl entity = em.find(MyEntityImpl.class, 1L);

但是,当我运行此代码时,我发现有第二个查询,沿着主查询获取 Info 实体,就像 EAGER 行为一样。

我正在使用 @OneToOne 映射关系。我已经尝试了 FetchTypeoptional@LazyToOne 的多种组合,但到目前为止没有成功。

以下是 MyEntity 和 MyEntityInfo 类的代码(删除了额外的 getter 和 setter):

MyEntity(ID生成器是自定义序列生成器):

@Entity
@Table(name = MyEntityImpl.TABLE_NAME)
public class MyEntityImpl {

public static final String TABLE_NAME = "TMP_MY_ENTITY";

@Id
@GeneratedValue(strategy = GenerationType.TABLE, generator = "GEN_" +
TABLE_NAME)
@GenericGenerator(name = "GEN_" +
TABLE_NAME, strategy = CoreIdGenerator.ID_GENERATOR, parameters = {
@Parameter(name = "tableName", value = TABLE_NAME) })
@Column(name = "sid", nullable = false, unique = true)
private Long sid;

@OneToOne(mappedBy = "myEntity", cascade = CascadeType.ALL, fetch = FetchType.LAZY, optional = true)
@LazyToOne(LazyToOneOption.NO_PROXY)
private MyEntityInfoImpl info;

@Column
private String field;

我的实体信息:

@Entity
@Table(name = MyEntityInfoImpl.TABLE_NAME)
public class MyEntityInfoImpl {
public static final String TABLE_NAME = "TMP_MY_ENTITY_INFO";

@Id
@Column(name = "SID", nullable = false, unique = true)
private Long sid;

@OneToOne(fetch = FetchType.EAGER, optional = false)
@JoinColumn(name = "SID", referencedColumnName = "SID", insertable = false, updatable = false, nullable = false)
private MyEntityImpl myEntity;

@Column(name = "INFO_FIELD")
private String infoField;

我尝试过这个解决方案,但正如我所说,它对我不起作用:

Hibernate lazy loading for reverse one to one workaround - how does this work?

我已经成功地使用 @OneToMany 并手动管理数据做了一些类似的事情,但这不是我想要做的。但是,我们也欢迎其他替代方案以及有关是否可以使用 @OneToOne 或正确的设计模式来实现此目的的信息。

PS:为 SQL Server 创建数据库表,如果您想尝试一下:

create table TMP_MY_ENTITY (SID NUMERIC(19,0) NOT NULL, FIELD VARCHAR(100));
go
ALTER TABLE TMP_MY_ENTITY ADD CONSTRAINT PK_TMP_MY_ENTITY PRIMARY KEY CLUSTERED (SID);
go

create table TMP_MY_ENTITY_INFO (SID NUMERIC(19,0) NOT NULL, INFO_FIELD VARCHAR(100));
go
ALTER TABLE TMP_MY_ENTITY_INFO ADD CONSTRAINT PK_TMP_MY_ENTITY_INFO PRIMARY KEY CLUSTERED (SID);
go

CREATE SEQUENCE SEQ_TMP_MY_ENTITY START WITH 1 INCREMENT BY 1 MINVALUE 1 CACHE 20;

alter table TMP_MY_ENTITY_INFO add constraint FK_TMP_MY_ENT_INFO_MY_ENT FOREIGN KEY (SID) references TMP_MY_ENTITY(SID);
go

insert into TMP_MY_ENTITY(SID, FIELD) VALUES (NEXT VALUE FOR SEQ_TMP_MY_ENTITY, 'Field 1');
insert into TMP_MY_ENTITY_INFO(SID, INFO_FIELD) VALUES ((SELECT MAX(SID) FROM TMP_MY_ENTITY), 'Info 1');

insert into TMP_MY_ENTITY(SID, FIELD) VALUES (NEXT VALUE FOR SEQ_TMP_MY_ENTITY, 'Field 2');
insert into TMP_MY_ENTITY_INFO(SID, INFO_FIELD) VALUES ((SELECT MAX(SID) FROM TMP_MY_ENTITY), 'Info 2');

insert into TMP_MY_ENTITY(SID, FIELD) VALUES (NEXT VALUE FOR SEQ_TMP_MY_ENTITY, 'Field 3 no info');

-- DELETE ALL

drop table TMP_MY_ENTITY_INFO;
drop table TMP_MY_ENTITY;
drop sequence SEQ_TMP_MY_ENTITY;

最佳答案

遵循@SternK链接并升级到Wildfly 19和Hibernate 5.4.14后,它终于通过使用@MapsId工作了。

正确使用的映射是这样的:

我的实体:

public class MyEntityImpl {

@OneToOne(mappedBy = "myEntity", cascade = CascadeType.REMOVE, fetch = FetchType.LAZY, optional = true)
@JoinColumn(name = "SID")
private MyEntityInfoImpl info;

我的实体信息:

public class MyEntityInfoImpl {

@OneToOne(fetch = FetchType.EAGER, optional = false)
@MapsId
@JoinColumn(name = "SID", referencedColumnName = "SID", insertable = false, updatable = false, nullable = false)
private MyEntityImpl myEntity;

关于java - Hibernate OneToOne 之间具有惰性行为的 PK,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61140887/

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