ling
ling

Reputation: 1675

JPA @JoinColumn and relationship between entities

In this example from https://docs.oracle.com/javaee/7/tutorial/persistence-criteria002.htm

@Entity
public class Pet {
    @Id
    protected Long id;
    protected String name;
    protected String color;

    @ManyToOne
    protected Set<Person> owners;
    ...
}

I have two questions on this:

1) Why isn't there a @JoinColumn annotation below @ManyToOne?

2) Why isn't there a qualifier in @ManyToOne( targetEntity = Person.class )?

3) Does this @ManyToOne mean that many Persons map to one Pet? If that's the case, why is it Set owners? I thought it should be just

@ManyToOne
protected Person owner;

In this example:

@Entity
public class Company {
    @OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
    private List<Branch> branches;
}

@Entity
public class Branch {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "companyId")
    private Company company;
}

In the "@JoinColumn(name = "companyId")", why isn't there " referencedColumnName =id"? Is it valid?

Upvotes: 0

Views: 1695

Answers (3)

v.ladynev
v.ladynev

Reputation: 19976

Looks like it is incorrect

@ManyToOne
protected Set<Person> owners;

It should be

@ManyToMany
protected Set<Person> owners;

or

@ManyToOne
@JoinColumn
protected Person owner;

So @JoinColumn can't be used with a @ManyToMany association, because of a join table is used for such associations. Anyway, when it is appropriate, I always use @JoinColumn to make a mapping more clear.

Why isn't there a qualifier in @ManyToOne( targetEntity = Person.class)?

It can be figured out by generic Set<Person>. So it is not need to specify. And It doesn't help to understand mapping.

In the "@JoinColumn(name = "companyId")", why isn't there " referencedColumnName =id"? Is it valid?

Hibernate does association using the id property of a Company by default. It is valid.

Summary

I see a lot of mappings with dozens unnecessary annotations. It is very hard to understand. Please, use only those annotations that do mapping more clear.

Upvotes: 2

alvgarvilla
alvgarvilla

Reputation: 1086

1) Why isn't there a @JoinColumn annotation below @ManyToOne?

For the same reason that id, name and color do not have the @Column annotation. The name of the field is the same than the one in the DB table. When this happen, you do not need to include the @Column or @JoinColumn annotation (as well as @Table)

2) Why isn't there a qualifier in @ManyToOne( targetEntity = Person.class )?

You are already saying which is the target entity with Set.

In the "@JoinColumn(name = "companyId")", why isn't there " referencedColumnName =id"? Is it valid?

You do not neet to do so, in the Company @Entity, I guess that you have an @Id annotation in some field.

Upvotes: 1

mh-dev
mh-dev

Reputation: 5533

The JoinColumn annotation is not mandatory. I am not sure why so many tutorials use this annotation since it only overrides the default behaviour. When they do not like the default generated name a custom naming strategy would be the better choice.

To keep it short:

  1. There is not JoinColumn annotation, because its optional and someone has decided not to use it. Maybe he wants the default behaviour.
  2. TargetEntity is only necessary if the related entity is different than the one in the model. (Maybe another implementation of a class)

Upvotes: 0

Related Questions