无法使用 @IdClass 转换实体中的请求元素

Posted

技术标签:

【中文标题】无法使用 @IdClass 转换实体中的请求元素【英文标题】:Failed to convert request element in entity with @IdClass 【发布时间】:2017-01-04 06:54:51 【问题描述】:

我有以下设置:

@Entity
@IdClass(MemberAttributePk.class)
public class MemberAttribute 
    @Id
    @ManyToOne @JoinColumn(name="member_id")
    protected Member member;

    @Id
    protected String name;

    private String value;

    public MemberAttribute() 

    // get & set

还有id类:

public class MemberAttributePk implements Serializable 
    protected Member member;
    protected String name;

    public MemberAttributePk() 

    // get & set

我已经为MemberAttribute 定义了一个简单的 Spring Data 存储库:

@Repository
public interface MemberAttributeRepo extends JpaRepository<MemberAttribute, MemberAttributePk> 

现在,我要做的就是将成员属性持久化到数据库中:

public void saveAttribute(Member member, String name, String value) 
    MemberAttribute attr = new MemberAttribute(member, name, value);
    attributeRepo.save(attr);

但是,我最终得到了这个服务器异常:

2016-08-28 00:24:20.673  WARN 5656 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : 
Failed to convert request element: org.springframework.beans.ConversionNotSupportedException: 
Failed to convert property value of type [java.lang.Long] to required type [com.example.Member] for property 'member'; nested exception is java.lang.IllegalStateException: 
Cannot convert value of type [java.lang.Long] to required type [com.example.Member] for property 'member': 
no matching editors or conversion strategy found

知道我做错了什么吗? 谢谢!

【问题讨论】:

【参考方案1】:

只是您的代码不符合 JPA。问题的原因是您使用Member 作为您的PK 的一部分。 PK只能由以下Java类型的字段组成

    原语 : boolean , byte , char , int , long , short java.lang : Boolean , Byte , Character , Integer , Long , Short , String , Enum , StringBuffer java.math:BigInteger java.sql:日期、时间、时间戳 java.util:日期、货币、语言环境、时区、UUID java.net:URI、URL javax.jdo.spi:PersistenceCapable

这应该可行:

@Embeddable
public class MemberAttributePk implements Serializable 
    @Column(name = "member_id")
    protected Long memberId;
    @Column(name = "name")
    protected String name;

    public MemberAttributePk() 

    // get & set


@Entity
public class MemberAttribute 

    @EmbeddedId
    protected MemberAttributePk memberAttributePk;

    @ManyToOne 
    @JoinColumn(name="member_id")
    protected Member member;

    private String value;

    public MemberAttribute() 

    // get & set

或者@ClassId也一样

public class MemberAttributePk implements Serializable 
    protected Long memberId;
    protected String name;

    public MemberAttributePk() 

    // get & set


@Entity
@IdClass(MemberAttributePk.class)
public class MemberAttribute 
    @Id
    @Column(name = "member_id")
    protected Long memberId;

    @Id
    @Column(name = "name")
    protected String name;

    @ManyToOne 
    @JoinColumn(name="member_id")
    protected Member member;

    private String value;

    public MemberAttribute() 

    // get & set

【讨论】:

谢谢!而已。顺便提一下Member 应该映射为:@ManyToOne @JoinColumn(name="member_id", insertable = false, updatable = false)【参考方案2】:

您可以尝试使用您的 MemberRepository 保存它,因为我相信您的 Member 类和 MemberAttribute 类具有一对多的关系引用,下面是示例

会员等级

@Entity
public class Member 

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

    @OneToMany(mappedBy = "Member", cascade = CascadeType.ALL)
     private Set<MemberAttribute> mMemberAttributes = new HashSet<>();

     public void setMemberAttributes(Set<MemberAttribute> mMemberAttributes)
        this.mMemberAttributes = mMemberAttributes;
     

     public Set<MemberAttribute> getMemberAttributes()
         return mMemberAttributes;
     

     // other code

MemberRepository 类

public interface MemberRepository extends JpaRepository<Member, Long> 


保存函数中的代码

public void saveAttribute(Member member, String name, String value) 
    MemberAttribute attr = new MemberAttribute(member, name, value);
    member.getMemberAttributes().add(attr);
    memberRepository.save(member);

【讨论】:

以上是关于无法使用 @IdClass 转换实体中的请求元素的主要内容,如果未能解决你的问题,请参考以下文章

Tapestry 5.3.8 + Jetty + Hibernate 4.3.5 + XAMPP 1.8.3 - IdClass 使用(派生)实体,为啥在尝试合并时它们会分离?

@IdClass 使用 JPA 和 Hibernate 生成“实例标识符已更改”

css元素定位:通过元素的标签或者元素的idclass属性定位

使用实体的复合键作为另一个实体中的 ManyToMany 键

java.lang.IllegalArgumentException:期待 IdClass 映射

IdClass 未在类“Hello”中定义