Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Embedded field does not work after upgrading to Hibernate 5.0.6.Final in Spring Boot 1.3.1.RELEASE

Having a embeddable class MultiLanguageText:

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

And another class that uses this class twice:

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

The fields got translated perfectly fine into "name_textDe", "description_textDe", "name_textFr" and so on with the spring version 1.2.7.RELEASE.

However to store LocalDate's I wanted to upgrade to Hibernate 5. I followed the process described here: https://github.com/spring-projects/spring-boot/issues/2763#issuecomment-154419889

The process worked fine but the translation of the embedded fields stoped working *. I tried different implicit_naming_strategy and physical_naming_strategy, but non of them worked.

If I annotate the fields as follows it does work, but the process is somewhat cumbersome:

@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;

*Not working does mean I get an exception something along the lines of (as now the field gets mapped without the fieldname prefix and therefore the field exist twice):

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
like image 945
leo Avatar asked Jan 04 '16 16:01

leo


2 Answers

To fix this in Spring Boot 1.4, add this to your application.yaml:

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

From the javadocs:

An ImplicitNamingStrategy implementation which uses full composite paths extracted from AttributePath, as opposed to just the terminal property part. Mainly a port of the older DefaultComponentSafeNamingStrategy class implementing the no longer supported NamingStrategy contract.

like image 134
btiernay Avatar answered Nov 07 '22 10:11

btiernay


Hibernate official documentation says:

If you want to have the same embeddable object type twice in the same entity, the column name defaulting will not work as several embedded objects would share the same set of columns. In plain JPA, you need to override at least one set of columns. Hibernate, however, allows you to enhance the default naming mechanism through the NamingStrategy interface. You can write a strategy that prevent name clashing in such a situation. DefaultComponentSafeNamingStrategy is an example of this.

Consequently, if you wish to have full JPA compliance, stick with your current implementation.

like image 31
Guy Bouallet Avatar answered Nov 07 '22 08:11

Guy Bouallet