【问题标题】:Spring JPA findByEmail not working with @ManyToMany column joinSpring JPA findByEmail 不适用于 @ManyToMany 列连接
【发布时间】:2020-10-31 12:36:36
【问题描述】:

只要我将带有 @JoinColumn 的 @ManyToOne 映射添加到我的实体并执行 findBy 派生查询方法,就会得到 org.hibernate.PropertyAccessException: Could not set field value 异常。

ERROR 90376 --- [nio-8080-exec-1] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.orm.jpa.JpaSystemException: Could not set field value [User(name=null, email=email@gmail.com, accountState=ACTIVE, profilePicture=null, otpJsonString=null, company=null)] value by reflection : [class com.example.entity.User.company] setter of com.example.entity.User.company; nested exception is org.hibernate.PropertyAccessException: Could not set field value [User(name=null, email=email@gmail.com, accountState=ACTIVE, profilePicture=null, otpJsonString=null, company=null)] value by reflection : [class com.example.entity.User.company] setter of com.example.entity.User.company] with root cause

java.lang.IllegalArgumentException: Can not set com.example.entity.Company field com.example.entity.User.company to com.example.entity.User
package com.example.entity;

import lombok.*;

import javax.persistence.*;

@Entity
@Getter
@Setter
@ToString
@AllArgsConstructor
@NoArgsConstructor
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class BaseEntity {

    @Id
    @GeneratedValue
    @Basic(optional = false)
    private Long id;
}

package com.example.entity;

import lombok.*;
import lombok.experimental.SuperBuilder;
import org.springframework.data.annotation.CreatedBy;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.LastModifiedBy;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.jpa.domain.support.AuditingEntityListener;

import javax.persistence.EntityListeners;
import javax.persistence.MappedSuperclass;
import java.time.Instant;

@Getter
@Setter
@ToString
@MappedSuperclass
@NoArgsConstructor
@EntityListeners(AuditingEntityListener.class)
public abstract class Auditable<T> extends BaseEntity {

    @CreatedBy
    protected T createdBy;
    @CreatedDate
    protected Instant createdAt;
    @LastModifiedBy
    protected T lastModifiedBy;
    @LastModifiedDate
    protected Instant lastModifiedAt;

    public Auditable(Long id) {
        super(id);
    }
}

package com.example.entity;

import lombok.*;
import org.hibernate.annotations.Fetch;
import org.hibernate.annotations.FetchMode;

import javax.persistence.*;
import java.io.Serializable;

@Getter
@Setter
@Entity
@ToString
@EqualsAndHashCode
@NoArgsConstructor
public class User extends Auditable<String> implements Serializable {

    @NonNull
    private String name;
    @NonNull
    private String email;
    @NonNull
    private String accountState; //ACTIVE, BLOCKED, DELETED
    private String profilePicture;
    private String otpJsonString;
    @ManyToOne(optional = false)
    @JoinColumn(name = "Company_Id", referencedColumnName = "Id")
    private Company company;

    public User(Long id, String name, String email, Company company,
                String profilePicture, String accountState, String otpJsonString) {
        super(id);
        this.name = name;
        this.email = email;
        this.accountState = accountState;
        this.company = company;
        this.profilePicture = profilePicture;
        this.otpJsonString = otpJsonString;
    }
}

package com.example.entity;

import lombok.*;

import javax.persistence.*;
import java.io.Serializable;
import java.util.Set;

@Getter
@Setter
@Entity
@ToString
@EqualsAndHashCode
@NoArgsConstructor
@Table(indexes = {
        @Index(name = "website_unq_idx", columnList = "website", unique = true),
        @Index(name = "emailDomain_unq_idx", columnList = "emailDomain", unique = true),
})
public class Company extends Auditable<String> implements Serializable {

    @NonNull
    private String name;
    @NonNull
    private String logo;
    @NonNull
    private String website;
    @NonNull
    private String accountState; //ACTIVE, BLOCKED, DELETED
    @NonNull
    private String emailDomain;

    public Company(Long id, String name, String logo, String website, String accountState,
                                    String emailDomain) {
        super(id);
        this.name = name;
        this.logo = logo;
        this.website = website;
        this.accountState = accountState;
        this.emailDomain = emailDomain;
    }
}

这是触发的弹簧查询:

Hibernate: 
    select
        user0_.id as id1_0_,
        user0_.created_at as created_1_4_,
        user0_.created_by as created_2_4_,
        user0_.last_modified_at as last_mod3_4_,
        user0_.last_modified_by as last_mod4_4_,
        user0_.account_state as account_5_4_,
        user0_.email as email6_4_,
        user0_.company_id as comp_ch10_4_,
        user0_.name as name7_4_,
        user0_.otp_json_string as otp_json8_4_,
        user0_.profile_picture as profile_9_4_ 
    from
        user user0_ 
    where
        user0_.email=? 
        and user0_.account_state<>?
package com.example.repository;

import com.example.entity.User;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;

import java.util.List;
import java.util.Optional;

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
   
    Optional<User> findByEmailAndAccountStateNot(String email, String accountState);
}

【问题讨论】:

  • 添加了存储库
  • 数据库中Company_Id是否有空值?
  • createdBy、lastModifiedBy、logo 为空。休息有价值。
  • 删除导致问题的optional=false 并从 BaseEntity 类中删除 @Entity
  • 瞧!那行得通!谢谢@Eklavya :)

标签: java spring-boot hibernate spring-data-jpa


【解决方案1】:

文档中的optional

关联是否可选。如果设置为 false 则为非空 关系必须始终存在。

所以对于optional = false,JPA 期望在数据库中始终为该对象提供数据。删除它以不映射Company 对象

【讨论】:

    猜你喜欢
    • 2015-12-11
    • 2016-07-12
    • 2021-06-12
    • 2018-07-03
    • 1970-01-01
    • 2023-03-06
    • 1970-01-01
    • 2021-03-01
    • 1970-01-01
    相关资源
    最近更新 更多