1

I can't propper map DB tables with JPA annotation. db

Tables Subject and Place is ManyToMany through JoinTable.

Subject.java

@Entity
@Table(name = "SUBJECT")
public class Subject implements Serializable {
    @Id
    @Column(name = "SID")
    private Integer sid;

    @Column(name = "NAME")
    private String name;

    // getters and setters
}

SubjectPlace.java

@Entity
@Table(name = "SUBJECT_PLACE")
public class SubjectPlace implements Serializable {
    @Id
    @Column(name = "SPID")
    private Integer spid;

    @ManyToOne
    @JoinColumn(name = "SUB_KEY") //Subject FK
    private Subject subject;

    @ManyToOne
    @JoinColumn(name = "PLC_KEY") //Place FK
    private Place place;

    // getters and setters
}

Place.java

@Entity
@Table(name = "PLACE")
public class Place implements Serializable {
    @Id
    @Column(name = "PID")
    private Integer pid;

    @Column(name = "NAME")
    private String name;

    @ManyToMany(fetch = FetchType.LAZY, cascade = CascadeType.PERSIST)
        @JoinTable(name = "SUBJECT_PLACE",
            joinColumns = { @JoinColumn(name = "PLC_KEY", nullable = false, updatable = false) },
            inverseJoinColumns = { @JoinColumn(name = "SUB_KEY", nullable = false, updatable = false) })
    private Set<Subject> subjects;

    // getters and setters
}

But than I need to link Person with Subject in selected Places. I mean that each Place has its own collection of Subject. And a Person have link to Subject whitch resides in particular Place.

like This:

Subject (M) -- (M) Place through JoinTable Subject (1) -- (M) Subject_Place (M) -- (1) Place

Person (M) -- (M) Subject_Place through JoinTable Person (1) -- (M) Person_Subject_Place (M) -- (1) Subject_Place

Person.java

@Entity
@Table(name = "PERSON")
public class Person implements Serializable {
    @Id
    @Column(name = "PRSID")
    private Integer prsid;

    @Column(name = "NAME")
    private String name;

    // How to annotate this code?
    // I experience problem in this part of code
    @OneToMany
    @JoinColumn(name="SPID_KEY") 
    private List<SubjectPlace> subjectPlaces;

    // getters and setters
}

PersonSubjectPlace.java

@Entity
@Table(name = "PERSON_SUBJECT_PLACE")
public class PersonSubjectPlace implements Serializable {
    @Id
    @Column(name = "PSPID") // Person_Subject_Place ID
    private Integer pspid;

    @ManyToOne
    @JoinColumn(name = "PER_KEY") //Person FK
    private Person person;

    // How to annotate this code?
    // I experience problem in this part of code
    @ManyToOne
    @JoinColumn(name = "SPID_KEY") //Subject_Place FK
    private SubjectPlace subjectPlace;

    // getters and setters
}

And when I try so get Persons and its Subjects, I get this error: Caused by: org.hibernate.MappingException: Foreign key (FK2C3B79384AABC975:PERSON_SUBJECT_PLACE [SPID_KEY])) must have same number of columns as the referenced primary key (SUBJECT_PLACE [PLC_KEY,SUB_KEY])

What, How shoul I map?

miroque
  • 320
  • 1
  • 5
  • 21

2 Answers2

0

You should remove @Joincolumn annotation and add mappedBy variable to @OneToMany annotation.

@OneToMany(mappedBy = "spid")

You should have a variable in SubjectPlace that has a Person where you should put @JoinColumn annotation

cнŝdk
  • 31,391
  • 7
  • 56
  • 78
sgpalit
  • 2,676
  • 2
  • 16
  • 22
  • No, that's not worked.And I didn't understand about "variable in SubjectPlace that has a Person" – miroque May 26 '15 at 07:15
0

In your OneToMany mapping you don't need to specify the foreign key, you just need to use mappedBy property to refer your mapping object, you can learn more about it in OneToMany Mapping Documentation, and here's what you need to map Person and PersonSubjectPlace entities:

In your Person class:

@OneToMany(mappedBy="person")
private List<PersonSubjectPlace> personsubjectPlaces;

In your PersonSubjectPlace class:

@ManyToOne
@JoinColumn(name="PRSID") //Specify the primary key of Person
private Person person;

For further information about the difference between JoinColumn and mappedBy you can take a look at this answer.

EDIT:

For the mapping between SubjectPlace and PersonSubjectPlace:

In your SubjectPlace class:

@OneToMany(mappedBy="subjectPlace")
private List<PersonSubjectPlace> personsubjectPlaces;

In your PersonSubjectPlace class:

@ManyToOne
@JoinColumn(name="SPID") //Specify the primary key of SubjectPerson
private SubjectPlace subjectPlace;

Note:

The best approach to map those classes is to use @JoinTable between Person and SubjectPlace, take a look at this @JoinTable example, because PersonSubjectPlace is pratically an asociation-entity between Person and SubjectPlace.

Community
  • 1
  • 1
cнŝdk
  • 31,391
  • 7
  • 56
  • 78
  • Thanks for links to additional info. I've update question with Image of DB diagram. Unfortunately I can't see how to implement you answer, yet. Maybe I stare in wrong direction... – miroque May 26 '15 at 08:09
  • In that case yopu should place the second part of the code in my answer in the `PersonSubjectPlace` class instead of `SubjectPlace`. – cнŝdk May 26 '15 at 08:13
  • Yep, this is woks for Person and PersonSubjectPlace. But it fails when PersonSubjectPlace links with SubjectPlace. It can't link this FK with PK, and shows me this error, what in question – miroque May 26 '15 at 08:29
  • @miroque Use the same type of mapping used with `Person` and `PersoSubjectPlace`, take a look at my EDIT. – cнŝdk May 26 '15 at 08:56
  • unfortunatley it didn't work also. In i-net I've found some [similar problem](http://www.coderbag.com/NHibernate/Foreign-key-must-have-same-number-of-columns-as-the-referenced-primary-key) but author done his task, but in 2011 year... – miroque May 26 '15 at 10:16
  • 1
    The best approach for those classes is to use `@JoinTable` between `Person` and `SubjectPlace`, take a look at [**this @JoinTable example**](http://fruzenshtein.com/hibernate-join-table-intermediary/). – cнŝdk May 26 '15 at 10:21
  • thanks for another link, yep i've done my code to work, i don't know how, but it helped with `@JoinTable` principals... i give my code after time. maybe it's not optimal but... – miroque May 26 '15 at 10:59
  • @miroque was this answer helpful for you? if so please accept it. – cнŝdk Jul 16 '15 at 08:50