Sometimes you just want to map a list of primitive types. For example, a Book entity has a list of tags and tags are just strings. So you want to do the following :
[sourcecode language=”java”]
@Entity
public class Book {
@Id
@GeneratedValue
private Long id;
private String title;
private Float price;
private String description;
private String isbn;
private Integer nbOfPage;
private List<String> tags = new ArrayList<String>();
…
}
[/sourcecode]
What happens when you do this with JPA 1.0 ? The ArrayList implements Serializable so the entire list gets serialized into a blob column. What are the other choices ? Well, because JPA maps entities, you can create a Tag entity (with an ID and a value) and have a list of tags :
[sourcecode language=”java”]
Entity
public class Book {
@Id
@GeneratedValue
private Long id;
…
private List<Tag> tags = new ArrayList<Tag>();
…
}
@Entity
public class Tag {
@Id
@GeneratedValue
private Long id;
private String value;
…
}
[/sourcecode]
That’s a shame to create a separate entity when what you want is just a String. Now with JPA 2.0 you can use the @ElementCollection annotation on a list :
[sourcecode language=”java”]
@Entity
public class Book {
@Id
@GeneratedValue
private Long id;
…
@ElementCollection
@CollectionTable(name ="tags")
private List<String> tags = new ArrayList<String>();
…
}
[/sourcecode]
If you then want to find all the books that have the tag ‘scifi’, you can just write the following JPQL query :
[sourcecode language=”sql”]
SELECT b FROM Book b WHERE b.tags = ‘scifi’
[/sourcecode]
I didn’t manage to make this query work with Hibernate 3.6. So I had to rewrite the JPQL statement usgin a JOIN. This way, the query works on both EclipseLink and Hibnerate
[sourcecode language=”sql”]
SELECT b FROM Book b JOIN b.tags t WHERE t = ‘scifi’
[/sourcecode]
Download the code of this example. It uses EclipseLink 2.0-M9 and the Derby database.
