Convertir la liste dans entity en colonne à chaîne simple dans la base de données
j'ai un champ VARCHAR
dans ma base de données, et la valeur de ce champ est val1,val2,val3
.
est-il possible de définir cela dans un attribut ArrayList<String>
d'une entité utilisant la virgule comme délimiteur de division?
2 réponses
si vous utilisez JPA 2.1, alors vous pouvez créer un AttributeConverter
:
@Converter
public class StringListConverter implements AttributeConverter<List<String>, String> {
@Override
public String convertToDatabaseColumn(List<String> list) {
// Java 8
return String.join(",", list);
// Guava
return Joiner.on(',').join(list);
}
@Override
public List<String> convertToEntityAttribute(String joined) {
return new ArrayList<>(Arrays.asList(joined.split(",")));
}
}
Vous pouvez utiliser ce convertisseur dans votre entité:
@Column
@Convert(converter = StringListConverter.class)
private List<String> strings;
pour avant JPA 2.1 vous pourriez faire ceci à la main:
@Entity
private MyEntity {
...
private String strings;
public List<String> getStrings() {
return Arrays.asList(strings.split(","));
}
public void setStrings(List<String> list) {
strings = String.join(",", list);
}
}
I wrap Arrays.asList
dans un ArrayList
dans le convertisseur, parce que le résultat est stocké dans l'attribut et tout changement à cette liste sera réécrit à la base de données - donc j'ai besoin d'une liste modifiable (Je ne peux pas ajoutez n'importe quoi au résultat de Arrays.asList
). Dans la solution avant 2.1 le résultat n'est pas lié à l'attribut et une liste modifiable ne serait pas synchronisée avec l'attribut.
pour rechercher une entité qui contient un élément spécifique dans un tel attribut, voir ma réponse ici
Oui c'est possible.
Avec Hibernation 4.3.x + vous pouvez définir un AttributeConverter
bien que je suis assez sûr que cela ne fonctionnera pas pour les premières versions Hibernées à cause du type List
. Voir cet exemple: http://www.thoughts-on-java.org/jpa-21-how-to-implement-type-converter/
l'autre façon de faire ce travail est en mettant en œuvre un UserType
personnalisé et annotant le champ / getter avec org.hibernate.annotations.Type
. Voici une belle écriture de ce avec des exemples: http://blog.xebia.com/understanding-and-writing-hibernate-user-types/
encore une autre façon qui est compatible JPA est d'avoir deux champs, le List
annoté avec javax.persistence.Transient
et le String
mais alors vous avez gérer la synchronisation d'état entre ces deux champs dans PrePersist
et PreUpdate
auditeurs vous-même. Voici un exemple d'utilisation d'auditeurs: http://alexandregama.org/2014/03/23/entity-listeners-and-callback-methods-jpa/