在Spring Boot 1.3.1.RELEASE

时间:2016-01-04 16:03:16

标签: java hibernate spring-boot

有一个可嵌入的类MultiLanguageText:

@Embeddable
public class MultiLanguageText {
@Field
private String textDe;
@Field
private String textFr;
@Field
private String textIt;
//...
}

另一个使用此类两次的类:

@Entity(name = "T_AnotherClass")
public class AnotherClass{
@Id
@GeneratedValue
private long key;
@Embedded
private MultiLanguageText name;
@Embedded
private MultiLanguageText description;
//...
}

使用spring版本1.2.7.RELEASE将字段完全转换为“name_textDe”,“description_textDe”,“name_textFr”等等。

但是为了存储LocalDate,我想升级到Hibernate 5.我按照这里描述的过程进行了操作:https://github.com/spring-projects/spring-boot/issues/2763#issuecomment-154419889

这个过程运行正常,但嵌入式字段的转换停止工作*。我尝试了不同的implicit_naming_strategy和physical_naming_strategy,但没有使用它们。

如果我按如下方式对字段进行注释,它确实有效,但这个过程有点麻烦:

@Embedded
@AttributeOverrides({
        @AttributeOverride(name = "textDe", column = @Column(name = "name_textDe", length = MultiLanguageText.MAX_TEXT_LENGTH)),
        @AttributeOverride(name = "textFr", column = @Column(name = "name_textFr", length = MultiLanguageText.MAX_TEXT_LENGTH)),
        @AttributeOverride(name = "textIt", column = @Column(name = "name_textIt", length = MultiLanguageText.MAX_TEXT_LENGTH)),
})
private MultiLanguageText name;

*不工作意味着我得到一个例外的东西(因为现在字段被映射而没有字段名前缀,因此该字段存在两次):

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: AnotherClass column: textDe (should be mapped with insert="false" update="false")
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:764)
    at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:782)
    at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:778)
    at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:804)
    at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:539)
    at org.hibernate.mapping.RootClass.validate(RootClass.java:265)
    at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:329)
    at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:443)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:879)
    ... 48 more

2 个答案:

答案 0 :(得分:9)

要在Spring Boot 1.4中解决此问题,请将其添加到application.yaml

spring.jpa.hibernate.naming.implicit-strategy: org.hibernate.boot.model.naming.ImplicitNamingStrategyComponentPathImpl

来自javadocs

  

使用完整复合的ImplicitNamingStrategy实现   从AttributePath中提取的路径,而不仅仅是终端   财产部分。主要是老年人的港口   DefaultComponentSafeNamingStrategy类不再实现   支持NamingStrategy合同。

答案 1 :(得分:1)

Hibernate官方文档说:

  

如果要在同一个中使用相同的可嵌入对象类型两次   实体,列名默认不会像多个嵌入式一样工作   对象将共享同一组列。在普通的JPA中,你需要   覆盖至少一组列。然而,Hibernate允许你   通过NamingStrategy增强默认命名机制   接口。您可以编写一个策略来防止名称冲突   一种情况。 DefaultComponentSafeNamingStrategy就是一个例子。

因此,如果您希望完全遵守JPA,请坚持使用当前的实施方案。