ma3574
ma3574

Reputation: 447

Hibernate - One to Many Mapping of Set - Annotations

Newbie to Hibernate here. I'm building a simple app to play around with Hibernate and I'm getting the hang of most of the annotations but the mappings are really confusing me.

I have a Person class and I have a Note's class. A person can have many notes associated with them but a single note will only ever correspond to a specific person.

I'm trying to set it up so that the note table has a column called person_id such that I won't need an extra person_note table in the database for the associations.

How would I go about setting up the annotations such that an extra table is not created in the database and I can associate multiple notes to a single person via an extra column in the note's table?

I've tried a few options after searching on Google such as using annotations like this but with no luck:

@JoinColumn(name="id_person", nullable=false)

Person Class

@Entity
@Table(name = "person")
public class Person {

    @OneToMany()
    private Set<Note> notes;

    public Set<Note> getNotes() {
        return notes;
    }

    public void setNotes(Set<Note> notes) {
        this.notes = notes;
    }

    ...

}

Note Class

@Entity
@Table (name = "note")
public class Note {

    @ManyToOne
    private Person person;

    public Person getPerson() {
        return person;
    }

    public void setPerson(Person person) {
        this.person = person;
    }

   ...

}

Any help would be appreciated. Thank you.


Final Working Solution

For the benefit of anyone looking in the future, I now don't have a separate table for mapping note objects to people objects. The final code (with extra lines removed) now looks like this:

Person Class

@Entity
@Table(name = "person")
public class Person {

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "person", cascade = CascadeType.ALL)
    private Set<Note> notes;

    ...

}

Note Class

@Entity
@Table (name = "note")
public class Note {

    @ManyToOne(fetch = FetchType.EAGER)
    @JoinColumn(name = "id_person", nullable = false)
    private Person person;

   ...

}

Misc Points

Upvotes: 2

Views: 2967

Answers (3)

Deian
Deian

Reputation: 1374

I agree with you. One can implement what you're asking with only the two tables you already have.

Here is what I would do:

Database wise:

Table Person, with: PK column: person_id

Table Note, with:

  1. PK column: note_id
  2. column: person_id (nullable)
  3. column: assigned_person_id (nullable with unique index)

Purpose:

  1. person_id - reference to the PK of the Person table. That will define the [Person : Note] relationship, where 1 person can have multiple notes.

  2. assigned_person_id - reference to the person assigned to the note. However to guarantee your requirement that only one person can be assigned to a note - add an unique index by that column. That will guarantee that the same person_id was on used for another note record.

Hibernate wise:

Note that the code snippet is not complete! It is just pointing the important moments. You can look at one of the many complete examples, for instance: http://www.mkyong.com/hibernate/hibernate-one-to-many-relationship-example-annotation/

public class Person {

   @OneToMany(fetch = FetchType.LAZY, mappedBy = "person")
   public setNotes(Set<Note> notes) { 
     this.notes=notes;
   }

...          
}

@Table(name = "note", catalog = "schema_name", 
uniqueConstraints = @UniqueConstraint(columnNames = "assigned_person_id"))    
public class Note {    
  private Person person;
  private Person assignedPerson;

  @ManyToOne(fetch = FetchType.LAZY)
  @JoinColumn(name = "person_id", nullable = false)
  public Person getPerson() {
    return person;
  }

  public Person getAssignedPerson() {
    return assignedPerson;
  }

  ...

}

Upvotes: 0

cнŝdk
cнŝdk

Reputation: 32145

In your mapping annotations you should map the entities with a mappedBy property in the @OneToMany annotation and specify a joinColumn under the @ManyToOne annotation using the @JoinColumn annotation, Change your code like this:

Person class:

@OneToMany(mappedBy = "person") // "person" here refers to the person property in the notes class
private Set<Note> notes;

Notes class:

@ManyToOne
@JoinColumn(name = "id_person", nullable = false)
private Person person;

Take a look at Hibernate Collection mapping for further information.

Upvotes: 2

Saif
Saif

Reputation: 7042

Edit Person

@OneToMany(fetch = FetchType.EAGER , mappedBy = "person")
private Set<Note> notes;

And Note

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "person_id", nullable = false)
private Person person;

Upvotes: 1

Related Questions