猿问

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

假设我有两个实体(省略了 getter/setter):


@Entity

@Table

public 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

@Table

public class B {

    @Id

    @GenericGenerator(name="gen",strategy = "BIdentityGenerator")

    @GeneratedValue(generator = "gen")

    private Long id;

    @Column

    private String reason;

    @Column

    private Boolean requiresDetails;

}

这两个表是这样链接的:


Table A

-------

id

b_id (foreign key to primary key in B)

details


Table B

-------

id

reason (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);

紫衣仙女
浏览 149回答 2
2回答

临摹微笑

您应该CascadeType.ALL从实体 A 中删除。您应该拥有 DAO,它基于 返回您的实体 B reason,例如entityA.setEntityB(entityBDao.findBy(reason))
随时随地看视频慕课网APP

相关分类

Java
我要回答