Mateusz Gebroski
Mateusz Gebroski

Reputation: 1334

Unable to find column with logical name: user_details_id in org.hibernate.mapping.Table(user_details) and its related supertables and secondary tables

I am trying to create simple unidirectional mapping. I am using MappedSuperclass and @JoinColumn and there is probably a problem. Looks like entity cannot find id field from super class.

Exception:

Caused by: org.hibernate.MappingException: Unable to find column with logical name: user_details_id in org.hibernate.mapping.Table(user_details) and its related supertables and secondary tables
    at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:832) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:256) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:101) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1827) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1771) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1658) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:287) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:904) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:935) ~[hibernate-core-5.3.7.Final.jar:5.3.7.Final]

Super class:

@Getter
@Setter
@MappedSuperclass
public abstract class BaseEntity {

    @Id
    @GeneratedValue(
            strategy =  GenerationType.IDENTITY
    )
    private Long id;

}

Message entity (Joins id's of both sender and receiver)

@Getter
@Setter
@NoArgsConstructor
@AllArgsConstructor
@Builder
@Entity(name = "Message")
@Table(name = "message")
public class Message extends BaseEntity {
    private String title;
    private String details;
    private String message_container;
    private LocalDate dataOfSending;

    @ManyToOne(optional = false)
    @JoinColumn(name = "sender_id", referencedColumnName = "user_details_id")
    private UserDetails sender;

    @ManyToOne(optional = false)
    @JoinColumn(name = "receiver_id", referencedColumnName = "user_details_id")
    private UserDetails receiver;
}

User Details (should not know about messages)

@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Entity(name = "UserDetails")
@Table(name = "user_details")
public class UserDetails extends BaseEntity {

    private String firstName;
    private String lastName;
    private String motherName;
    private String fatherName;
    private String personalIdentityNum;
    private LocalDate dateOfBirth;

    @OneToOne
    @JoinColumn(name = "user_id")
    private User user;

    @OneToOne(mappedBy = "userDetails")
    private Address address;

    @OneToOne(mappedBy = "userDetails")
    private Contact contact;

    @OneToOne(mappedBy = "userDetails")
    private ProfileImage profileImage;

}

Any ideas? Thank you in advance.

Upvotes: 4

Views: 9880

Answers (2)

Dmitriy Popov
Dmitriy Popov

Reputation: 2350

Not sure that it will solve your problem, but I've just run in the same problem. The trick is that in SpringBoot, you have to reference the logical id, NOT the db column name.

My case:

PlayerEntity has playerId that generates the column named player_id. This is a @NaturalId.

In the other entity, I wrote a @ManyToOne, which fails on setting referencedColumnName = "player_id":

[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.MappingException: Unable to find column with logical name: player_id in org.hibernate.mapping.Table(player) and its related supertables and secondary tables

Since is says "logical name", I tried to change player_id to playerId (name of the field in PlayerEntity, and everything is working now:

    @ManyToOne
//    @JoinColumn(name = "player_id", referencedColumnName = "player_id") // fails
    @JoinColumn(name = "player_id", referencedColumnName = "playerId") // works! What the...
    private PlayerEntity player;

This works, column with a correct FK is generated:

    constraint FK6aw598iko4dicfrfa6sj0mni1
        foreign key (player_id) references player (player_id)

This actually looks like a bug in Spring JPA or Hibernate. Database is MySQL 8.1.

Upvotes: 1

Avijit Barua
Avijit Barua

Reputation: 3086

Can you just change this section in Message class

   @ManyToOne(optional = false)
    @JoinColumn(name = "sender_id", referencedColumnName = "user_details_id")
    private UserDetails sender;

    @ManyToOne(optional = false)
    @JoinColumn(name = "receiver_id", referencedColumnName = "user_details_id")
    private UserDetails receiver;

to

    @ManyToOne
    @JoinColumn(name = "sender_id")
    private UserDetails sender;

    @ManyToOne
    @JoinColumn(name = "receiver_id")
    private UserDetails receiver;

And in UserDetails add these code

 @OneToMany(mappedBy = "sender")
private List<Message> senderMessage = new ArrayList<>();

@OneToMany(mappedBy = "receiver")
private List<Message> receiverMessage = new ArrayList<>();

Upvotes: 5

Related Questions