JPA:覆盖组合键的自动生成的ID? [英] JPA: Override Auto generated ID for composite key?

查看:247
本文介绍了JPA:覆盖组合键的自动生成的ID?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

添加此问题用于文档目的,并检查是否有其他替代解决方案.

Adding this question for documentation purpose, and to check if there is any alternative solution.

我有一个实体,该实体具有使用@IdClass

I have an entity which has a composite key defined using @IdClass

data class TemplateId(var id: Long? = null, var version: Int = 0) : Serializable

@Entity
@IdClass(TemplateId::class)
data class Template(
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "sequenceGenerator")
    @SequenceGenerator(name = "sequenceGenerator")
    var id: Long? = null,

    @Id
    @Column(name = "version")
    var version: Int

    //Other columns
)

Idea对于Template的不同版本具有相同的ID.插入新模板时,使用Sequence Generator可以按预期工作. 但是,当我尝试插入具有相同ID的新版本行时,@GeneratedValue会覆盖给定值并自动递增为新值. JPA:覆盖自动生成的ID 中提到的解决方案 不起作用.

Idea is to have same ID for different versions of the Template. Using Sequence generator works as expected while inserting new template. But when I try to insert a new version row with same ID, @GeneratedValue overrides the given value and autoincrements to new value. Solution mentioned in JPA: Override Auto generated ID does not work.

推荐答案

我尝试了以下选项,但没有用.

I tried out following options and none worked.

  • 如问题中所述,不能使用@GeneratedValue替换其给定值

无法用自定义生成器( @GenericGenerator )替换@SequenceGenerator,不适用于复合广告钥匙.它尝试将Long值强制转换为IdClass TemplateId

Cannot replace @SequenceGenerator with custom generator (@GenericGenerator), doesn't work with composite key. It tries to cast Long value to IdClass TemplateId

我正在使用Postgres,因此尝试对id使用列类型SERIAL.这不适用于组合键上的IDENTITY GenerationType.存在一个存在的问题: HHH-9662

I am using Postgres, so tried using column type SERIAL for id. This does not work with IDENTITY GenerationType on composite key. There is an existing issue : HHH-9662

无法使用具有NULL值的数据库自动递增,postgres给出约束违反错误

Cannot use DB auto-increment with NULL value, postgres gives constraint violation error

"insertable"=false/ "updatable"=false不适用于@Id

类似地尝试使用休眠的@DynamicInsert,以便它会在插入查询中跳过空列值,但即使在@Id

Similarly tried using hibernate's @DynamicInsert so that it will skip null column values in insert query, but even that doesn't work with @Id

最后必须重写Spring的JpaRepositorysave功能以使其正常工作

Finally had to override the save function of Spring's JpaRepository to make it work

interface CustomTemplateRepository<S> {
    fun <E: S> save(entity: E): E
    fun <E: S> saveAndFlush(entity: E): E
}


class TemplateRepositoryImpl(
    private val jdbcTemplate: NamedParameterJdbcTemplate,
    @PersistenceContext private val entityManager: EntityManager
) : CustomTemplateRepository<Template> {
    override fun <E : Template> save(entity: E): E {
        if(entity.id == null)
            entity.id = jdbcTemplate.queryForObject("select nextval('sequence_generator')", 
                              mutableMapOf<String, Any>(), Long::class.java)
        entityManager.persist(entity)
        return entity
    }

    override fun <E : Template> saveAndFlush(entity: E): E {
        return save(entity).also {
            entityManager.flush()
        }
    }
}

这篇关于JPA:覆盖组合键的自动生成的ID?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆