Hibernate @AttributeOverride works on Entity but not on property

Viewed 564

Hibernate version 5.4.29 (tested standalone) or 5.4.28 (tested with SpringBoot 2.4.3)

Following models: Embeddable Book

import javax.persistence.Embeddable;
    
@Embeddable
public class Book {
    public Book() { }
        
    private String name = "";
    private String author = "";
    
    // ctors, getters, setters removed for brevity 
        
}

Event embedding 2 Books (book and ebook)

@Entity
@Table( name = "EVENTS" )
/*@AttributeOverrides({
    @AttributeOverride(name = "book.name", column = @Column(name = "book_title")), 
    @AttributeOverride(name = "book.author", column = @Column(name = "book_author")),
    @AttributeOverride(name = "ebook.name", column = @Column(name = "ebook_title")), 
    @AttributeOverride(name = "ebook.author", column = @Column(name = "ebook_author"))
})*/
public class Event {
   private Long id;
   private String title;
   private Date date;
        
   @Embedded
   @AttributeOverrides({
      @AttributeOverride(name = "name", column = @Column(name = "book_title")), 
      @AttributeOverride(name = "author", column = @Column(name = "book_author")),
   })
   private Book book = new Book();
        
   @Embedded
   @AttributeOverrides({
      @AttributeOverride(name = "name", column = @Column(name = "ebook_title")), 
      @AttributeOverride(name = "author", column = @Column(name = "ebook_author")),
   })
   private Book ebook = new Book();
    
   // ctors, getters, setters removed for brevity 
}

When try to configure @AttributeOverride on Entity (as shown in comments - it works), but when on concrete @Embedded property of type Book it doesn't work. Receiving following error:

    Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.example.demo.Event.Event column: author (should be mapped with insert="false" update="false")
        at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:862) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
        at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:880) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
        at org.hibernate.mapping.PersistentClass.checkPropertyColumnDuplication(PersistentClass.java:876) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
        at org.hibernate.mapping.PersistentClass.checkColumnDuplication(PersistentClass.java:902) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
        at org.hibernate.mapping.PersistentClass.validate(PersistentClass.java:634) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
        at org.hibernate.mapping.RootClass.validate(RootClass.java:267) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
        at org.hibernate.boot.internal.MetadataImpl.validate(MetadataImpl.java:354) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
        at org.hibernate.internal.SessionFactoryImpl.<init>(SessionFactoryImpl.java:298) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
        at org.hibernate.boot.internal.SessionFactoryBuilderImpl.build(SessionFactoryBuilderImpl.java:468) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]
        at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:1259) ~[hibernate-core-5.4.28.Final.jar:5.4.28.Final]

Persisting Entity

Event e = new Event( "A booked event", new Date() );
e.getBook().setAuthor("Jora K Jr");
e.getBook().setName("Book Name");
entityManager.persist( e3 );

I am doing something wrong? In Hibernate 4, AFAIR - it worked.

1 Answers

Most likely you get this error because you try to mix up access strategies and hibernate just ignore your @AttributeOverride annotations. By default, the placement of the @Id annotation gives the default access strategy.

So, try to correct your entity mapping in this way:

@Entity
@Table( name = "EVENTS" )
public class Event {

    @Id
    private Long id;

    // ...
    
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "name", column = @Column(name = "book_title")), 
        @AttributeOverride(name = "author", column = @Column(name = "book_author")),
    })
    private Book book = new Book();
    
    @Embedded
    @AttributeOverrides({
        @AttributeOverride(name = "name", column = @Column(name = "ebook_title")), 
        @AttributeOverride(name = "author", column = @Column(name = "ebook_author")),
    })
    private Book ebook = new Book();

    //ctors, getters, setters removed for brevity 

}

P.S. However, if you need you can override the default access strategy by using @Access annotation.

Related