85

I am trying to use Hibernate annotation for writing a model class for my database tables.

I have two tables, each having a primary key User and Question.

@Entity
@Table(name="USER")
public class User
{
    @Id
    @Column(name="user_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

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

    // Getter and setter
}

Question Table.

@Entity
@Table(name="QUESTION")
public class Questions extends BaseEntity{

    @Id
    @Column(name="question_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

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

    // Getter and setter
}

And I have one more table, UserAnswer, which has userId and questionId as foreign keys from the above two tables.

But I am unable to find how I can reference these constraints in the UserAnswer table.

@Entity
@Table(name="UserAnswer ")
public class UserAnswer
{
    @Column(name="user_id")
    private User user;

    //@ManyToMany
    @Column(name="question_id")
    private Questions questions ;

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

    // Getter and setter
}

How can I achieve this?

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
vikiiii
  • 9,246
  • 9
  • 49
  • 68

3 Answers3

82

@Column is not the appropriate annotation. You don't want to store a whole User or Question in a column. You want to create an association between the entities. Start by renaming Questions to Question, since an instance represents a single question, and not several ones. Then create the association:

@Entity
@Table(name = "UserAnswer")
public class UserAnswer {

    // this entity needs an ID:
    @Id
    @Column(name="useranswer_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne
    @JoinColumn(name = "question_id")
    private Question question;

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

    //getter and setter 
}

The Hibernate documentation explains that. Read it. And also read the javadoc of the annotations.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
  • Thank you so much for replying. Is it necessary to create a new column in the table as useranswer_id ? Is it possible if i can make the other two ids as composite keys? – vikiiii Mar 15 '13 at 07:43
  • 3
    It is possible, but it's bad design, painful, hard to use, and inefficient. Do the right thing, and assign an autogenerated, single-column ID to all your entities. – JB Nizet Mar 15 '13 at 07:46
  • @JB_Nizet I dont mind adding a id column to an entity . But do i need to add a column in table also? I mean oracle database. – vikiiii Mar 15 '13 at 07:48
  • Yes, of course. Where would Hibernate store the ID of the entity if the ccorresponding column doesn't exist? – JB Nizet Mar 15 '13 at 07:52
  • I asked my team lead. I can't add the column . I have to make them composite keys. I tried using @ EmbeddedId and @ Embeddable . But i get a hibernate exception – vikiiii Mar 15 '13 at 08:43
  • org.hibernate.AnnotationException: No identifier specified for entity . It can't find user_id – vikiiii Mar 15 '13 at 08:43
  • You must use the MapsId annotation. See http://docs.oracle.com/javaee/6/api/javax/persistence/MapsId.html, it has an example. – JB Nizet Mar 15 '13 at 08:51
  • Hi When i follow this example, i got the following exception bject references an unsaved transient instance - save the transient instance before flushing: com.product.domain.Users – Senthil Muthiah Sep 19 '13 at 12:50
  • if you are getting unsaved transient instance as exception then you need to add transaction annotation at service level.in service layer where we call the DAO objects to perform the task and it will return to the service layer on the top of the respected method,we need to mention @Transaction. – zameer Mar 23 '16 at 09:42
  • I am new to this thing and I am wondering, In this answer, how is the question_id set and saved to DB, because now the entity expects the whole question object. Isn't it? – Saurabh Tiwari Dec 04 '17 at 18:02
16

There are many answers and all are correct as well. But unfortunately none of them have a clear explanation.

The following works for a non-primary key mapping as well.

Let's say we have parent table A with column 1 and another table, B, with column 2 which references column 1:

@ManyToOne
@JoinColumn(name = "TableBColumn", referencedColumnName = "TableAColumn")
private TableA session_UserName;

Enter image description here

@ManyToOne
@JoinColumn(name = "bok_aut_id", referencedColumnName = "aut_id")
private Author bok_aut_id;
Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
Vaibhav Jain
  • 1,939
  • 26
  • 36
2

@JoinColumn(name="reference_column_name") annotation can be used above that property or field of class that is being referenced from some other entity.

engin
  • 27
  • 1
  • 6