【问题标题】:Hibenate "Parameter value did not match expected type"休眠“参数值与预期类型不匹配”
【发布时间】:2020-11-29 04:16:22
【问题描述】:

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

我的实体类有 Collections 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&lt;Completed&gt; 对象传递给自定义@Query@Param?为什么类型不匹配?

【问题讨论】:

    标签: java spring-boot hibernate collections orm


    【解决方案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);
    

    【讨论】:

    • 我不确定我是否遵循。我以为List 扩展了Collections,所以这是可以接受的类型?你是说我应该创建一个超类型Collections&lt;Completed&gt; collection = new ArrayList&lt;&gt;() 的对象,这会被接受吗?我确实也尝试过创建一个可变的ArrayList&lt;&gt;() 并将其作为参数传递,我留下了一个注释行来暗示这一点,但应该说清楚。仍然抛出异常。所以在这种情况下,使用 FK 的关系数据库并不理想,创建/使用新表会更容易吗?谢谢。
    • 将集合类型更改为更通用的类型不会解决该问题。这里的问题不在于您使用什么集合类型,而在于使用集合。为了让 Hibernate 有机会更改此集合,集合的可变性在这里是必要的,并且对于此集合中的所有实体,将 user_id 属性设置为您创建的用户实体的 id。我不知道您的意思是“创建/使用新表会更容易”-请解释一下。如果你想建立一个@OneToMany 关系,你必须创建一个新表。
    猜你喜欢
    • 1970-01-01
    • 2021-08-05
    • 2016-07-13
    • 1970-01-01
    • 2018-09-02
    • 2016-04-22
    • 2015-12-13
    • 2016-09-18
    • 2014-04-06
    相关资源
    最近更新 更多