ivanjermakov
ivanjermakov

Reputation: 1284

Repeated column in mapping for entity in @OneToOne unidirectional mapping

Consider the following database structure

I need to implement unidirectional one to one mapping like that (structure is simplified):

@Entity
@Table(name = "entity")
public class Customer {

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

    @OneToOne
    @JoinColumn(name = "customer_info", nullable = false)
    private CustomerInfo customerInfo;

    @OneToOne
    @JoinColumn(name = "customer_credentials", nullable = false)
    private CustomerCredentials customerCredentials;

    //  getter, setters etc
}

@Entity
@Table(name = "customer_info")
public class CustomerInfo {

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

    //  getter, setters etc
}

@Entity
@Table(name = "customer_credentials")
public class CustomerCredentials {

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

    //  getter, setters etc
}

But somehow hibernate unable to differentiate that those joins are from different tables and throws such error:

Caused by: org.hibernate.MappingException: Repeated column in mapping for entity: com.example.Customer column: customer_id (should be mapped with insert="false" update="false")

Important notice: I do not want to use @OneToOne(mappedBy = "customer") because I need cascade save functionality

Upvotes: 0

Views: 416

Answers (1)

Luisa Emme
Luisa Emme

Reputation: 390

You can use @JoinTable instead of @JoinColumn to solve your problem:

@Entity @Table(name = "entity") public class Customer {

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

    @OneToOne(cascade = CascadeType.ALL, targetEntity = CustomerInfo.class)
    @JoinTable(name = "customer_info", inverseJoinColumns = {@JoinColumn(name = "customer_id", nullable = false)})
    private CustomerInfo customerInfo;

    @OneToOne(cascade = CascadeType.ALL, targetEntity = CustomerCredentials.class)
    @JoinTable(name = "customer_credentials", inverseJoinColumns = {@JoinColumn(name = "customer_id", nullable = false)})
    private CustomerCredentials customerCredentials;

    //  getter, setters etc }

@Entity @Table(name = "customer_info") public class CustomerInfo {

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

    //  getter, setters etc }

@Entity @Table(name = "customer_credentials") public class CustomerCredentials {

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

    //  getter, setters etc }

You could change the cascade strategy to any strategy you need. I just left CascadeType.ALL there as an example.

Upvotes: 2

Related Questions