Reputation: 430
I am still fairly new to Hibernate and I am still on a steep learning curve. I have an application that will track which people were on which event and visa-versa. I have an Event Class and a Person Class linked via a jointable.
I have forms and helper classes that allow me to enter the data on the separate Person and Event classes, persist it, search it, delete it, change it and list it. This is all tested and working.
When I add people to the event I can list all the events and see the list of people attached to the events but when I output the list of People they all have an Event list of size 0.
It is my understanding that if I attach a person to an event that the person should show up in Event.myPeople and that the event should show up in Person.eventList.
Clearly I am doing something wrong and I suspect that it is in my annotations and Declarations. I have listed both set for Event and Person classes below. Failing that I have a fundamental misunderstanding of Hibernate ,both are likely. On the bright side, the more mistakes I make the faster I learn.
Any idea where I am going wrong?
@Entity
@Table(name = "PERSON")
public class Person implements Serializable {
@Id
@GeneratedValue
@Column(name = "person_id")
private int ID;
private String foreName;
private String surName;
@Temporal(javax.persistence.TemporalType.DATE)
private Date dob; //used to differentiate people with same name
@Temporal(javax.persistence.TemporalType.DATE)
private Date joinDate; //used to filter events outside active dates
@Temporal(javax.persistence.TemporalType.DATE)
private Date endDate; //used to filter events outside active dates
private Boolean active;
@ManyToMany()//cascade=CascadeType.ALL)
@JoinTable(name = "PERSON_EVENT", joinColumns = @JoinColumn(name = "person_id"),
inverseJoinColumns = @JoinColumn(name = "event_id"))
private Set<Event> eventList;
@OneToOne
private Sections mySection;
@Entity
@Table(name = "EVENT")
public class Event implements Serializable {
@Id
@GenericGenerator(name = "generator", strategy = "increment")
@GeneratedValue(generator = "generator")
@Column(name="event_id")
private long id;
private String eventTitle;
private String eventDescription;
private String eventLocation;
@Temporal(javax.persistence.TemporalType.DATE)
private Date startDate;
@Temporal(javax.persistence.TemporalType.DATE)
private Date endDate;
@ManyToMany(cascade = CascadeType.ALL)
private Set<Person> myPeople;
@OneToMany(mappedBy = "myEvent")
private Set<EventType> type;
Upvotes: 0
Views: 604
Reputation: 64628
There is a common misconception about bidirectional relations in Hibernate. Hibernate does not care about consistency in your object tree. If there is a bidirectional relation between events and persons, you have to add the person to the event and the event to the person yourself. Hibernate only persists what you created in memory. Do not expect Hibernate to add any object to any collections, this is the responsibility of the business logic, which shouldn't rely on Hibernate to work properly.
Now, bidirectional relations are special in that inconsistent states in memory cannot even be persisted. With consistent data, Hibernate only has to persist one site of the bidirectional relation, because the other is (or should be) redundant. This is done by marking one part as the "inverse" part. (I'm sorry that I don't know annotation mapping syntax well enough to point to a possible error in you mapping.) "inverse" means to Hibernate nothing more then "ignore when syncing to database", because it is expected to be redundant.
You still have to make sure that the information in both collections are redundant. It actually "works" when you only add the items to the non-inverse collections. But, however, this is not recommended to do because the objects will not be consistent until saved and loaded into a new session.
Also make sure that the bidirectional relation is mapped to the same table using the same foreign keys. I don't know if annotation mapping does detect this automatically.
Hope that helps.
Upvotes: 2
Reputation: 86
The problem must be due to a missing mappedBy field in the many to many
associations.
The field that owns the relationship is required unless the relationship is unidirectional.
I think adding (mappedBy = eventList)
will suffice.
Upvotes: 1