Hibernate insert cascade not inserting foreign key

El Guapo picture El Guapo · Dec 21, 2010 · Viewed 16.3k times · Source

I have two entities:

@Entity
public class File
.......
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@OneToMany(fetch=FetchType.LAZY, mappedBy="file", cascade=CascadeType.ALL)
private List<Tag> tags;
.......
OTHER PROPERTIES
.......

@Entity
public class Tag
.......
@Id @GeneratedValue(strategy=GenerationType.AUTO)
private int id;
@ManyToOne
@JoinColumn(name="file_id")
private File file;
@Column
private String tag;
.......
OTHER PROPERTIES
.......

I am trying to insert into File (and subsequently Tag) by doing the following:

File file = new File();
Tag tag = new Tag();
tag.setTag("tag1");
Tag2 tag2 = new Tag();
tag2.setTag("tag2");
List<Tag> tags = new ArrayList<Tag>();
tags.add(tag);
tags.add(tag2);
file.setTags(tags);
---Add other file attributes here---

I am then inserting the file in my DAO using:

sessionFactory.getCurrentSession().saveOrUpdate(file); 

In my logs I see an insert into my "file" table and 2 inserts into my tag table, however, the foreign key in my tag table that points to my file table (file_id) is NULL.

What could I possibly be doing wrong?

Answer

jpkrohling picture jpkrohling · Dec 21, 2010

You are not setting the File for a Tag, just the Tag's to a File. Remember that in OOP, as opposed to the Relational Model, you have to set both ends of a relationship. You can't navigate from Tag to File just because you added a set of Tags to a File. In your case, you can just navigate from File to Tag (ie: list all Tags for a File). You can't tell which File a Tag belongs to, by looking only at the Tag.

What is usually done is a helper method in one of the models, like this:

public void addTag(Tag tag) {
  this.tags.add(tag);
  tag.setFile(this);
}

See this for an example (from Hibernate's test suite):