我已经创建了一个实体类,其中有一个列,该列使用JPA的属性转换器:
@Convert(converter = StringListConverter.class)
private List<String> functionSpecificationLabel;转换器类是:
@Converter
public class StringListConverter implements AttributeConverter<List<String>, String> {
@Override
public String convertToDatabaseColumn(List<String> list) {
return String.join(",", list);
}
@Override
public List<String> convertToEntityAttribute(String joined) {
return new ArrayList<>(Arrays.asList(joined.split(",")));
}
}表中列的预期值如下
functionSpecificationLabel
multiVLANSupport,telepresence,csaid现在,我需要在multiVLANSupport,telepresence,csaid列中返回以functionSpecificationLabel作为值的行。
我在存储库中的查询是:
@Query("Select pd from ProductDetailsEntity pd where pd.functionSpecificationLabel in (:labels)")
Optional<ProductDetailsEntity> findByFunctionSpecificationLabel(@Param("labels") final List<String> labels);现在我要面对的问题是:
Parameter value [multiVLANSupport] did not match expected type [java.util.List (n/a)]
发布于 2020-10-06 11:45:33
我不太确定这是否可能,下面是如何使用@ElementCollection在实体类中存储值列表的方法--您可以在这里更多地了解它-- https://thorben-janssen.com/hibernate-tips-query-elementcollection/
在这里可以找到一个很好的讨论,How to persist a property of type List in JPA?。我的建议是避免基于分隔符在db中存储任何值。
理想情况下,当存储这样的标签时,最好使用OneToMany关系映射它们。还请注意,这将创建一个额外的表,在本例中是animal_labels。
答案1
存储库
@Repository
public interface AnimalRepository extends JpaRepository<Animal, UUID> {
List<Animal> findDistinctAnimalsByLabelsIsIn(List<String> cute);
}实体类
@Entity
@Table(name = "animal")
public class Animal {
@Id
@GeneratedValue
@Type(type = "uuid-char")
private UUID id;
private String name;
@ElementCollection(targetClass = String.class)
private List<String> labels;
public Animal() {
}
public Animal(String name, List<String> labels) {
this.name = name;
this.labels = labels;
}
public UUID getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getLabels() {
return labels;
}
public void setLabels(List<String> labels) {
this.labels = labels;
}
}测试:
@ExtendWith(SpringExtension.class)
@Transactional
@SpringBootTest(classes = TestApplication.class)
class CustomConverterTest {
@Autowired
private EntityManager entityManager;
@Autowired
private AnimalRepository animalRepository;
@Test
void customLabelConverter() {
Animal puppy = new Animal("Puppy", Arrays.asList("cute", "intelligent", "spy"));
Animal meow = new Animal("Cat", Arrays.asList("cute", "intelligent"));
entityManager.persist(puppy);
entityManager.persist(meow);
List<Animal> animalWithCutelabels = animalRepository.findDistinctAnimalsByLabelsIsIn(Arrays.asList("cute"));
List<Animal> animalWithSpylabels = animalRepository.findDistinctAnimalsByLabelsIsIn(Arrays.asList("spy"));
List<Animal> animalWithCuteAndSpylabels = animalRepository.findDistinctAnimalsByLabelsIsIn(Arrays.asList("cute", "spy"));
Assertions.assertEquals(2, animalWithCutelabels.size());
Assertions.assertEquals(1, animalWithSpylabels.size());
Assertions.assertEquals(2, animalWithCuteAndSpylabels.size());
}
}答案2
如果您有任何选择,但只能使用逗号分隔的值,那么请在下面找到这种方法的答案:
存储库(因为这是一个字符串,所以不能像in那样使用列表)
@Repository
public interface AnimalRepository extends JpaRepository<Animal, UUID> {
// Also note that the query goes as string and not list
List<Animal> findAllByLabelsContaining(String labels);
}测试:
@Test
void customLabelConverter() {
Animal puppy = new Animal("Puppy", String.join(",", Arrays.asList("cute", "intelligent", "spy")));
Animal meow = new Animal("Cat", String.join(",", Arrays.asList("cute", "intelligent")));
entityManager.persist(puppy);
entityManager.persist(meow);
List<Animal> animalWithCutelabels = animalRepository.findAllByLabelsContaining(String.join(",", Arrays.asList("cute")));
List<Animal> animalWithSpylabels = animalRepository.findAllByLabelsContaining(String.join(",", Arrays.asList("spy")));
Assertions.assertEquals(2, animalWithCutelabels.size());
Assertions.assertEquals(1, animalWithSpylabels.size());
}实体:
@Entity
@Table(name = "animal")
public class Animal {
@Id
@GeneratedValue
@Type(type = "uuid-char")
private UUID id;
@Column
private String name;
@Column
private String labels;
public Animal() {
}
public Animal(String name, String labels) {
this.name = name;
this.labels = labels;
}
public UUID getId() {
return id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<String> getLabels() {
if (StringUtils.isEmpty(labels)) return Collections.emptyList();
return new ArrayList<>(Arrays.asList(labels.split(AnimalLabelsConverter.DELIMITER_COMMA)));
}
public void setLabels(List<String> labels) {
if (CollectionUtils.isEmpty(labels)) {
this.labels = "";
} else {
this.labels = String.join(AnimalLabelsConverter.DELIMITER_COMMA, labels);
}
}
@Converter
public static class AnimalLabelsConverter implements AttributeConverter<List<String>, String> {
private static final String DELIMITER_COMMA = ",";
@Override
public String convertToDatabaseColumn(List<String> labels) {
if (CollectionUtils.isEmpty(labels)) return "";
return String.join(DELIMITER_COMMA, labels);
}
@Override
public List<String> convertToEntityAttribute(String dbData) {
if (StringUtils.isEmpty(dbData)) return Collections.emptyList();
return new ArrayList<>(Arrays.asList(dbData.split(DELIMITER_COMMA)));
}
}
}https://stackoverflow.com/questions/64222005
复制相似问题