在 Hibernate 中的复合 @JoinColumns 上使用 AttribueConverter
Using AttribueConverter on a composite @JoinColumns in Hibernate
Hibernate(使用 Spring Boot JPA)在目标实体使用复合连接时无法插入,其中其中一列是使用转换器的自定义类型。
简化的实体定义:
@Entity
data class MyConfiguration(
@Id
val configurationId: Long,
val enabled: Boolean,
@OneToMany(
cascade = [CascadeType.ALL],
fetch = FetchType.EAGER,
orphanRemoval = true,
mappedBy = "id.configurationId"
)
val tables: Set<SourceTable>
)
@Embeddable
data class SourceTableId(
val configurationId: Long,
@Convert(converter = TableIdConverter::class)
val tableId: TableId
) : Serializable
@Entity
data class SourceTable(
@EmbeddedId
val id: SourceTableId,
@OneToMany(
cascade = [CascadeType.ALL],
fetch = FetchType.EAGER,
orphanRemoval = true
)
@JoinColumns(
JoinColumn(name = "configurationId", referencedColumnName = "configurationId", updatable = false),
JoinColumn(name = "tableId", referencedColumnName = "tableId", updatable = false)
)
val groupingFields: Set<TableGroupField> = emptySet()
)
@Embeddable
data class TableGroupFieldId(
val configurationId: Long,
@Convert(converter = TableIdConverter::class)
val tableId: TableId,
val fieldName: String
) : Serializable
@Entity
data class TableGroupField(
@EmbeddedId
val id: TableGroupFieldId
)
转换器 class 使用简单的字符串操作,TableId
class 实现 Serializable
。
从 Spring 引导应用程序的上下文中保存元素时,出现以下异常:
... Omitted for readability ...
Caused by: javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562) ~[spring-orm-5.3.8.jar:5.3.8]
... 33 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.Comparator.compare(Object, Object)" because the return value of "org.hibernate.type.descriptor.java.JavaTypeDescriptor.getComparator()" is null
at org.hibernate.type.AbstractStandardBasicType.compare(AbstractStandardBasicType.java:211) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.type.ComponentType.compare(ComponentType.java:217) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
... Omitted for readability ...
我确认将 TableId
列更改为简单字符串可以解决问题。我还应该申请其他任何东西来使其与此连接查询一起使用吗?
在这种情况下,id 或 id 的一部分的转换器只是偶然工作。有一个未解决的问题:https://hibernate.atlassian.net/browse/HHH-8820
Hibernate(使用 Spring Boot JPA)在目标实体使用复合连接时无法插入,其中其中一列是使用转换器的自定义类型。
简化的实体定义:
@Entity
data class MyConfiguration(
@Id
val configurationId: Long,
val enabled: Boolean,
@OneToMany(
cascade = [CascadeType.ALL],
fetch = FetchType.EAGER,
orphanRemoval = true,
mappedBy = "id.configurationId"
)
val tables: Set<SourceTable>
)
@Embeddable
data class SourceTableId(
val configurationId: Long,
@Convert(converter = TableIdConverter::class)
val tableId: TableId
) : Serializable
@Entity
data class SourceTable(
@EmbeddedId
val id: SourceTableId,
@OneToMany(
cascade = [CascadeType.ALL],
fetch = FetchType.EAGER,
orphanRemoval = true
)
@JoinColumns(
JoinColumn(name = "configurationId", referencedColumnName = "configurationId", updatable = false),
JoinColumn(name = "tableId", referencedColumnName = "tableId", updatable = false)
)
val groupingFields: Set<TableGroupField> = emptySet()
)
@Embeddable
data class TableGroupFieldId(
val configurationId: Long,
@Convert(converter = TableIdConverter::class)
val tableId: TableId,
val fieldName: String
) : Serializable
@Entity
data class TableGroupField(
@EmbeddedId
val id: TableGroupFieldId
)
转换器 class 使用简单的字符串操作,TableId
class 实现 Serializable
。
从 Spring 引导应用程序的上下文中保存元素时,出现以下异常:
... Omitted for readability ...
Caused by: javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.internal.ExceptionConverterImpl.convertCommitException(ExceptionConverterImpl.java:81) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.engine.transaction.internal.TransactionImpl.commit(TransactionImpl.java:104) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:562) ~[spring-orm-5.3.8.jar:5.3.8]
... 33 common frames omitted
Caused by: java.lang.NullPointerException: Cannot invoke "java.util.Comparator.compare(Object, Object)" because the return value of "org.hibernate.type.descriptor.java.JavaTypeDescriptor.getComparator()" is null
at org.hibernate.type.AbstractStandardBasicType.compare(AbstractStandardBasicType.java:211) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
at org.hibernate.type.ComponentType.compare(ComponentType.java:217) ~[hibernate-core-5.4.32.Final.jar:5.4.32.Final]
... Omitted for readability ...
我确认将 TableId
列更改为简单字符串可以解决问题。我还应该申请其他任何东西来使其与此连接查询一起使用吗?
在这种情况下,id 或 id 的一部分的转换器只是偶然工作。有一个未解决的问题:https://hibernate.atlassian.net/browse/HHH-8820