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?

22
demandé sur Tobias Liefke 2015-12-02 20:18:46

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

48
répondu Tobias Liefke 2018-05-29 12:09:16

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/

5
répondu Christian Beikov 2015-12-03 09:05:45