“Hibernate”:参数值与预期类型不匹配

huangapple go评论73阅读模式
英文:

Hibenate "Parameter value did not match expected type"

问题

我想将一个List<Completed>对象插入到一个关系表中,使用Spring框架和Hibernate。

我的实体类有一个List字段 -

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    ...
    
    @OneToMany(mappedBy = "user", cascade = CascadeType.ALL)
    private List<Completed> completedList;

    ... // getters/setters
}

数据访问仓库 -

public interface UserRepository extends CrudRepository<User, Long> {

    Optional<User> findByEmail(String email);

    @Modifying
    @Query(value = "update User set completedList = :completed where id = :id")
    @Transactional
    void addNewCompletion(@Param("completed") List<Completed> completed,
                          @Param("id") long userID);
}

我调用方法如下(用于测试目的) -

Completed completed1 = new Completed(1, LocalDateTime.now());
Completed completed2 = new Completed(2, LocalDateTime.now());
Completed completed3 = new Completed(3, LocalDateTime.now());
List<Completed> completedList = List.of(completed1, completed2, completed3);
//        completedList.add(completed1);
UserService.updateUserCompletion(completedList, UserService.findUserID(currentUser));

我还尝试过以下方式 -

List<Completed> completedList = new ArrayList<>();
completedList.add(new Completed()); // etc.
Completed completed = new Completed(1, LocalDateTime.now());
UserService.updateUserCompletion(completed, UserService.findUserID(currentUser));

不管哪种方式,都会导致相同的异常 -

java.lang.IllegalArgumentException: Parameter value [io.github.siaust.web_quiz_app.Model.Completed@2f1eafc2] did not match expected type [java.util.Collection (n/a)]

我不明白,因为我将List<Completed>对象传递给自定义@Query@Param,为什么类型不匹配?

英文:

I want to insert a List&lt;Completed&gt; objects into a relational table, using Spring framework and Hibernate.

My entity class has the Collections List field -

@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private long id;

    ...
    
    @OneToMany(mappedBy = &quot;user&quot;, cascade = CascadeType.ALL)
    private List&lt;Completed&gt; completedList;

    ... // getters/setters
}

The data access repository -

public interface UserRepository extends CrudRepository&lt;User, Long&gt; {

    Optional&lt;User&gt; findByEmail(String email);

    @Modifying
    @Query(value = &quot;update User set completedList = :completed where id = :id&quot;)
    @Transactional
    void addNewCompletion(@Param(&quot;completed&quot;) List&lt;Completed&gt; completed,
                          @Param(&quot;id&quot;) long userID);
}

I'm calling the method as such (for testing purposes) -

        Completed completed1 = new Completed(1, LocalDateTime.now());
        Completed completed2 = new Completed(2, LocalDateTime.now());
        Completed completed3 = new Completed(3, LocalDateTime.now());
        List&lt;Completed&gt; completedList = List.of(completed1, completed2, completed3);
//        completedList.add(completed1);
        UserService.updateUserCompletion(completedList, UserService.findUserID(currentUser));

I have also tried -

    List&lt;Completed&gt; completedList = new ArrayList()&lt;&gt;;
    completedList.add(new Completed()); // etc.
   Completed completed = new Completed(1, LocalDateTime.now());
   UserService.updateUserCompletion(completed, UserService.findUserID(currentUser));

Either which way results in the same exception -

java.lang.IllegalArgumentException: Parameter value [io.github.siaust.web_quiz_app.Model.Completed@2f1eafc2] did not match expected type [java.util.Collection (n/a)]

I can't understand as I am passing a List&lt;Completed&gt; object to the @Param of the custom @Query? Why does the type not match?

答案1

得分: 1

这样更新数据库关联是不可能的。Collections 是一个特定类型,以这种方式提供对象列表,Hibernate 无法识别它为列表并正确处理它。当你使用 @Query 时,Hibernate 简单地运行你的 SQL 代码。这意味着 Hibernate 将集合作为参数传递到你的 SQL 代码中,数据库服务器无法解析该集合。你还创建了一个不可变的集合,这在这里也行不通。我认为在你的情况下,以下代码应该能正常工作:

User user = UserService.findUserID(currentUser);

List<Completed> completedList = new ArrayList<>();
completedList.add(new Completed(1, LocalDateTime.now()));
completedList.add(new Completed(2, LocalDateTime.now()));
completedList.add(new Completed(3, LocalDateTime.now()));

user.setCompleted(completedList);
userRepository.save(user);
英文:

It's not possible to update database relations like this. Collections is a specific type and giving a list of object in that way you give Hibernate no change to recognize this as a list and handle it correctly. When you use @Query hibernate simply runs your SQL code. That means Hibernate passes into your SQL code a collection as a param and database server could not resolve that collection You also creating an immutable collection which is don't work here too. I think in your case this should work correctly:

User user = UserService.findUserID(currentUser);

List&lt;Completed&gt; completedList = new ArrayList&lt;&gt;();
completedList.add(new Completed(1, LocalDateTime.now()));
completedList.add(new Completed(2, LocalDateTime.now()));
completedList.add(new Completed(3, LocalDateTime.now()));


user.setCompleted(completedList);
userRepository.save(user);

huangapple
  • 本文由 发表于 2020年8月9日 18:42:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/63325289.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定