为了账号安全,请及时绑定邮箱和手机立即绑定

持久化时引用没有外键的静态表

持久化时引用没有外键的静态表

紫衣仙女 2021-07-09 21:01:08
假设我有两个实体(省略了 getter/setter):@Entity@Tablepublic class A {    private Long id;    private B b;    private String details;    @SequenceGenerator(name = "auto_gen", sequenceName = "a_sequence", allocationSize = 1)    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "auto_gen")    @Column(name="id",updatable = false,nullable = false)    @Id    public Long getId(){return id;}    @OneToOne(fetch = FetchType.LAZY,cascade = CascadeType.ALL)    @JoinColumn(name = "a_id")    public B getB(){        return b;    }}@Entity@Tablepublic class B {    @Id    @GenericGenerator(name="gen",strategy = "BIdentityGenerator")    @GeneratedValue(generator = "gen")    private Long id;    @Column    private String reason;    @Column    private Boolean requiresDetails;}这两个表是这样链接的:Table A-------idb_id (foreign key to primary key in B)detailsTable B-------idreason (unique)表 B 保存静态数据,因此永远不应插入新行。鉴于我有一个新对象 A 和与现有 db 对象 B 的实体关系,我想将 A 作为新行保留并链接到表 B 的现有行。我也想保留 A 而没有 id B 事先,只有唯一reason值。如果我在持久化 A 之前手动为 B 提供一个 id,这种情况就很好,但这种编码方式似乎有点麻烦。我想知道是否有办法通过 id 生成器来隐式设置 B 的 id 给定reason数据库中的值。我曾尝试使用 GenericGenerator 生成 id(见下文);然而,这有一个问题,它假设生成的值是一个全新的生成 id 并且违反了主键约束。我也考虑过使用实体侦听器,但文档指出他们不应该调用EntityManager.public class BIdentityGenerator implements IdentifierGenerator {    private static final String QUERY = "SELECT id FROM b WHERE reason = ?";    private static Logger log = LoggerFactory.getLogger(BIdentityGenerator.class);
查看完整描述

2 回答

?
临摹微笑

TA贡献1982条经验 获得超2个赞

您应该CascadeType.ALL从实体 A 中删除。您应该拥有 DAO,它基于 返回您的实体 B reason,例如entityA.setEntityB(entityBDao.findBy(reason))


查看完整回答
反对 回复 2021-07-14
  • 2 回答
  • 0 关注
  • 148 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信