2

I'm new to Ebean's world, and I encounter some difficulties to set some relationships between entities.

I have basically two classes, User and Car.

A user can have several cars (so I guess OneToMany) and a car can belongs to one User (so I guess OneToOne).

How can I link these two entities? Here it is what I've done so far

User

@Entity
public class User extends Model{
    @Id
    @GeneratedValue
    public int id;  
    public String name; 
    @ManyToMany(cascade=CascadeType.ALL)
    public List<Car> car = new ArrayList<Car>();
}

Car

@Entity
public class Car extends Model{
    @Id
    @GeneratedValue
    public int id;
    @OneToOne(cascade = CascadeType.ALL)
    public User user; 
}

And I get the following error

PersistenceException: Error on models.User.car Can not find mappedBy property [users] in [models.Car]

Can someone explain me clearly how to use annotations the correct way (very poor documentation), and tell me why I get this error?

Mornor
  • 3,471
  • 8
  • 31
  • 69

2 Answers2

6

You guessed wrong :)

Your User should have a @OneToMany relationship with cars so:

@OneToMany(mappedBy = "user", cascade=CascadeType.ALL)
public List<Car> car = new ArrayList<Car>();

while your Car should have a @ManyToOne relationship :

@ManyToOne(cascade = CascadeType.ALL)
public User user; 

Take care on the mappedBy property in the @OneToMany annotation: you need to tell Ebean where the foreign key lies in the related class.

Shanness
  • 365
  • 2
  • 10
davide
  • 1,918
  • 2
  • 20
  • 30
  • Thank you! Can you explain me more the mappedBy parameters? Is it a random name? I don't understand how and when I should use it. – Mornor Mar 02 '15 at 16:36
  • The mappedBy is not needed in this case because it can be inferred. – Shanness Mar 04 '15 at 14:30
1

User

@Entity
public class User extends Model{
@Id
@GeneratedValue
public int id;  
public String name; 
@OneToMany(cascade=CascadeType.ALL)
public List<Car> car = new ArrayList<Car>();
}

Car

@Entity
public class Car extends Model{

@Id
@GeneratedValue
public int id;
@ManyToOne(mappedBy="car")          //will give you an error
public User user; 
}

mappedBy here represents the owner of relation which is important in bidirectional relation.

Think in normal condition can a car exist without the User which owns it means User is the owner in a relation.So in your case User is the owner of relation.Mapped By

But the above code will not work The attribute mappedBy is undefined for the annotation type ManyToOne

In that case @JoinColumn come into picture.Join Column

Community
  • 1
  • 1
singhakash
  • 7,891
  • 6
  • 31
  • 65
  • I think finally get the logic. A car cannot exists without a User, this means the User is the owner of the relation, am I right? – Mornor Mar 02 '15 at 21:36
  • 1
    @Mornor you are right .Entity is a POJO(plain old java object) so you can relate it to OOPs like Parent and child class we use to study.Also you should be careful in using cascade in your relation like in my answer I only put cascade type all(means persist,delete etc) to User so if you delete User all the respective cars would be deleted but you dont want that behaviour in Car(that completely depends on your relation). – singhakash Mar 03 '15 at 05:05
  • You wrote the mappedBy into the Car class. So the owner of the relation is the User (because a car cannot exist without user). To be brief, the mappedBy has to be written in the class which is NOT the owner, right? MappedBy is undefined for ManyToOne annotation. – Mornor Mar 03 '15 at 08:09