Pearson Radu
Pearson Radu

Reputation: 23

Hibernate JPA Mapping Multiple Entities of the Same Type

I have a one-to-many relationship with Customer and Address, but I'm not sure how to represent this with JPA. I don't want use @OneToMany for the AddressEntity's in CustomerEntity because I want to avoid wrapping it in a Collection.

I'm wondering what annotation or even other strategies I can use to maintain the relationship where one customer will, for simplicity, always have two addresses. Any suggestions are appreciated!

Address Entity

@Data
@NoArgsConstructor
@Entity(name = "address")
public class AddressEntity
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @?
    private CustomerEntity customer;
}

Customer Entity

@Data
@NoArgsConstructor
@Entity(name = "customer")
public class CustomerEntity
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @?
    private AddressEntity shippingAddress;

    @?
    private AddressEntity billingAddress;
}

Upvotes: 1

Views: 1870

Answers (2)

v.ladynev
v.ladynev

Reputation: 19956

For the case when an address can belong different customers.

@Entity
public class AddressEntity
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

}

@Entity
public class CustomerEntity
{
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    private AddressEntity shippingAddress;

    @ManyToOne
    private AddressEntity billingAddress;

}

if each customer has unique address, better to store the addresses in the same customer record.

You can create class EmbeddedAddress and use @Embedded and @Embeddable annotations.

Upvotes: 1

x sylver
x sylver

Reputation: 119

For your exact scenario, I think you could go for @PostLoad. The steps would be:

  • use @OneToMany annotation to load the addresses into a collection
  • annotate both shippingAddress and billingAddress with @Transient
  • create a public method annotated with @PostLoad
  • initialise your 2 transient fields (you need to have at least an enum to discriminate between the addresses)

Why would the steps above work?

  • PostLoad is invoked after an entity is loaded from the database
  • the fields need to be transient, because they are not mapped to database columns

A relevant example can be found here.

While the approach above would solve your problem, it adds some degree of verbosity in your JPA entities. I would suggest to go for @OneToMany and make sure you add an enum in AddressEntity to check if an address is for shipping or billing.

Also, given that you mentioned that there is a one-to-many relationship between a customer and an address, then there is a many-to-one relationship between an address and a customer. The annotation to use in the AddressEntity class is @ManyToOne

Upvotes: 1

Related Questions