首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >参数值[multiVLANSupport]与预期类型[java.util.List (n/a)]不匹配

参数值[multiVLANSupport]与预期类型[java.util.List (n/a)]不匹配
EN

Stack Overflow用户
提问于 2020-10-06 08:25:49
回答 1查看 988关注 0票数 2

我已经创建了一个实体类,其中有一个列,该列使用JPA的属性转换器:

代码语言:javascript
复制
  @Convert(converter = StringListConverter.class)
  private List<String> functionSpecificationLabel;

转换器类是:

代码语言:javascript
复制
@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(",")));
    }

  }

表中列的预期值如下

代码语言:javascript
复制
functionSpecificationLabel
multiVLANSupport,telepresence,csaid

现在,我需要在multiVLANSupport,telepresence,csaid列中返回以functionSpecificationLabel作为值的行。

我在存储库中的查询是:

代码语言:javascript
复制
@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)]

EN

回答 1

Stack Overflow用户

发布于 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

存储库

代码语言:javascript
复制
@Repository
public interface AnimalRepository extends JpaRepository<Animal, UUID> {
    List<Animal> findDistinctAnimalsByLabelsIsIn(List<String> cute);
}

实体类

代码语言:javascript
复制
@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;
    }

}

测试:

代码语言:javascript
复制
@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那样使用列表)

代码语言:javascript
复制
@Repository
public interface AnimalRepository extends JpaRepository<Animal, UUID> {
    // Also note that the query goes as string and not list 
    List<Animal> findAllByLabelsContaining(String labels);
}

测试:

代码语言:javascript
复制
@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());
    }

实体:

代码语言:javascript
复制
@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)));
        }
    }
}
票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/64222005

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档