How to persist a property of type List<String> in JPA? How to persist a property of type List<String> in JPA? java java

How to persist a property of type List<String> in JPA?


Use some JPA 2 implementation: it adds a @ElementCollection annotation, similar to the Hibernate one, that does exactly what you need. There's one example here.

Edit

As mentioned in the comments below, the correct JPA 2 implementation is

javax.persistence.ElementCollection@ElementCollectionMap<Key, Value> collection;

See: http://docs.oracle.com/javaee/6/api/javax/persistence/ElementCollection.html


Sorry to revive an old thread but should anyone be looking for an alternative solution where you store your string lists as one field in your database, here's how I solved that. Create a Converter like this:

import java.util.Arrays;import java.util.List;import javax.persistence.AttributeConverter;import javax.persistence.Converter;import static java.util.Collections.*;@Converterpublic class StringListConverter implements AttributeConverter<List<String>, String> {    private static final String SPLIT_CHAR = ";";        @Override    public String convertToDatabaseColumn(List<String> stringList) {        return stringList != null ? String.join(SPLIT_CHAR, stringList) : "";    }    @Override    public List<String> convertToEntityAttribute(String string) {        return string != null ? Arrays.asList(string.split(SPLIT_CHAR)) : emptyList();    }}

Now use it on your Entities like this:

@Convert(converter = StringListConverter.class)private List<String> yourList;

In the database, your list will be stored as foo;bar;foobar, and in your Java object you will get a list with those strings.

Hope this is helpful to someone.


It seems none of the answers explored the most important settings for a @ElementCollection mapping.

When you map a list with this annotation and let JPA/Hibernate auto-generate the tables, columns, etc., it'll use auto-generated names as well.

So, let's analyze a basic example:

@Entity@Table(name = "sample")public class MySample {    @Id    @GeneratedValue    private Long id;    @ElementCollection // 1    @CollectionTable(name = "my_list", joinColumns = @JoinColumn(name = "id")) // 2    @Column(name = "list") // 3    private List<String> list;    }
  1. The basic @ElementCollection annotation (where you can define the known fetch and targetClass preferences)
  2. The @CollectionTable annotation is very useful when it comes to giving a name to the table that'll be generated, as well as definitions like joinColumns, foreignKey's, indexes, uniqueConstraints, etc.
  3. @Column is important to define the name of the column that'll store the varchar value of the list.

The generated DDL creation would be:

-- table sampleCREATE TABLE sample (  id bigint(20) NOT NULL AUTO_INCREMENT,  PRIMARY KEY (id));-- table my_listCREATE TABLE IF NOT EXISTS my_list (  id bigint(20) NOT NULL,  list varchar(255) DEFAULT NULL,  FOREIGN KEY (id) REFERENCES sample (id));