Преобразование списка в сущности в колонку с одной строкой в базе данных
В моей базе данных есть поле VARCHAR
, а значение этого поля - val1,val2,val3
.
Можно ли установить это в атрибут ArrayList<String>
объекта с использованием запятой в качестве разделителя разделителя?
Ответы
Ответ 1
Если вы используете JPA 2.1, вы можете создать 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(",")));
}
}
Вы можете использовать этот конвертер в своей сущности:
@Column
@Convert(converter = StringListConverter.class)
private List<String> strings;
Для до JPA 2.1 вы можете сделать это вручную:
@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);
}
}
Ответ 2
Да, это возможно.
С Hibernate 4.3.x + вы можете определить AttributeConverter
, хотя я уверен, что это не будет работать для ранних версий Hibernate из-за типа List
. См. Это для примера: http://www.thoughts-on-java.org/jpa-21-how-to-implement-type-converter/
Другой способ сделать эту работу - реализовать пользовательский UserType
и аннотировать поле/получатель с помощью org.hibernate.annotations.Type
. Вот хорошая запись этого примера: http://blog.xebia.com/understanding-and-writing-hibernate-user-types/
Другим способом, который совместим с JPA, является наличие двух полей: List
, аннотированных с помощью javax.persistence.Transient
и String
, но затем вы управляете синхронизацией состояния между этими двумя полями в PrePersist
и PreUpdate
слушатели сами. Вот пример использования слушателей: http://alexandregama.org/2014/03/23/entity-listeners-and-callback-methods-jpa/