java - 如何使用 Hibernate 基于现有列填充集合
问题描述
我有两个具有属性的现有表(someField
在示例代码中)。
我想要做的:用与我正在加载的实体具有相同值的Foo.bars
所有实体填充集合。Bar
someField
Foo
我不想创建额外的连接表,因为我不想显式更新关系。
我如何通过实体和/或其字段上的注释来实现这一点?
一些澄清:
- 这两
someField
列是独立修改的。 - 两列中的任何一列都没有唯一键约束(这就是我添加 的原因
@ManyToMany
)。 - 我不需要外键关系或任何级联。
- 如果修改了集合,则不应更新列。我希望休眠只在加载
Foo
实体时填充集合。 - 我尝试
@JoinFormula
在没有任何@XtoY
关系的情况下使用,但无法正常工作。 - 该关系仅从一侧建模,因为
Foo
如果我有Bar
实例,我从不关心 s。
我正在使用 spring-boot-starter-data-jpa 2.3,它使用 Hibernate 5.4.15
@Entity
public class Foo{
@Id
@GeneratedValue
private int id;
private int someField;
@ManyToMany
private Set<Bar> bars;
}
@Entity
public class Bar{
@Id
@GeneratedValue
private int id;
private int someField;
}
2020 年 6 月 22 日更新
由于我无法表达我的用例,我创建了一个最小的github 项目。
我发现实现所需行为的唯一两种方法是:
实现
Bar
手动加载关联实例的显式控制器逻辑。实现一个附加到手动获取关联实例的
FooRepository
加载方法的 AspectJ 方面。Bar
两者都“错了”,因为我认为这属于 hibernate 的范围,它会创建很多额外的数据库查询。
解决方案
所以首先,我不明白你为什么要使用@ManyToMany
,因为那是用于 n 对 n 关系而你的看起来不像那样。
您可以通过两种方式对父子关系进行建模,最有效的一种是 ManyToOne 映射,其中子代管理父代的外键:
@Entity
public class Parent {
@Id
@GeneratedValue
private int id;
private int someField;
}
@Entity
public class Child {
@Id
@GeneratedValue
private int id;
private int someField;
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(
name = "someField",
referencedColumnName = "someField",
unique = false,
updateable = false,
insertable = false)
private Parent parent;
}
你可以使用 JPQL/Criteria Queries 来获取你需要的一切。
有关“唯一”等属性,请参阅@JoinColumn 文档。
如果你坚持反过来做,那也可以:
@Entity
public class Parent {
@Id
@GeneratedValue
private int id;
private int someField;
@OneToMany(
// cascade = What operations do you want to cascade? Who is the owner of the relationship?
// orphanRemoval = Do you want to delete orphaned children?
)
@JoinColumn(name = "someField",
unique = false,
updateable = false,
insertable = false)
private List<Child> children = new ArrayList<>();
}
@Entity
public class Child {
@Id
@GeneratedValue
private int id;
private int someField;
}
这是一个单向映射,但如果您愿意,您可以将“父”关联添加到孩子。然后你必须添加方法以确保它们是同步的([见这里])4
如果它们不是唯一的并且没有外键,我不确定这是否可行。但在这种情况下,您可以使用@JoinFormula
提供 SQL 查询来连接。
推荐阅读
- python - 使用并行运行 html2text
- akka - 有没有办法让一个 Akka 节点知道另一个 Akka 节点是否重新启动
- vba - 尽管计算设置为手动,但在打开工作簿时不会禁用计算
- visual-studio-code - 每次在 VS Code 中打开新的终端窗口时,如何运行一些命令?
- javascript - AWS IoT Core 连接被经过身份验证的 Cognito 用户拒绝,带有附加策略 [MQTT over WSS]
- sql - 使用命令复制在 postgres 中出现变量连接问题
- android - Android Intent Share 无法正常工作
- corda - 使用 network-bootstrapper 生成节点信息需要带有 devMode=false 的证书
- php - 由于 .htaccess,php curl 出现 301 错误
- ios - Stripe STPAddCardViewController 导航栏未显示