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

2022-01-18 00:00:00 spring java Hibernate spring-data

我有以下设置:

@Entity@IdClass(MemberAttributePk.class)公共类成员属性 {@ID@ManyToOne @JoinColumn(name="member_id")受保护的会员;@ID受保护的字符串名称;私有字符串值;公共成员属性(){}//获取 &放}

还有id类:

public class MemberAttributePk 实现 Serializable {受保护的会员;受保护的字符串名称;公共 MemberAttributePk() {}//获取 &放}

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

@Repository公共接口 MemberAttributeRepo 扩展 JpaRepository<MemberAttribute, MemberAttributePk>{}

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

public void saveAttribute(Member member, String name, String value) {MemberAttribute attr = new MemberAttribute(member, name, value);属性Repo.save(attr);}

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

2016-08-28 00:24:20.673 WARN 5656 --- [nio-8080-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver :无法转换请求元素:org.springframework.beans.ConversionNotSupportedException:无法将类型 [java.lang.Long] 的属性值转换为属性成员"所需的类型 [com.example.Member];嵌套异常是 java.lang.IllegalStateException:无法将类型 [java.lang.Long] 的值转换为属性成员"所需的类型 [com.example.Member]:未找到匹配的编辑器或转换策略

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

解决方案

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

<块引用>

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

<小时>

这应该可行:

@Embeddable公共类 MemberAttributePk 实现 Serializable {@Column(name = "member_id")受保护的长成员 ID;@Column(名称 = "名称")受保护的字符串名称;公共 MemberAttributePk() {}//获取 &放}@实体公共类成员属性 {@EmbeddedId受保护的成员属性库成员属性库;@ManyToOne@JoinColumn(name="member_id")受保护的会员;私有字符串值;公共成员属性(){}//获取 &放}

或与 @ClassId

相同

public class MemberAttributePk 实现 Serializable {受保护的长成员 ID;受保护的字符串名称;公共 MemberAttributePk() {}//获取 &放}@实体@IdClass(MemberAttributePk.class)公共类成员属性 {@ID@Column(name = "member_id")受保护的长成员 ID;@ID@Column(名称 = "名称")受保护的字符串名称;@ManyToOne@JoinColumn(name="member_id")受保护的会员;私有字符串值;公共成员属性(){}//获取 &放}

I have the following setup:

@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
}

And the id class:

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

    public MemberAttributePk() {}

    // get & set
}

I have defined a simple Spring Data repository for MemberAttribute:

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

Now, all I want to do is persist a member attribute to the database:

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

However, I end up with this server exception:

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

Any idea what am I doing wrong? Thanks!

解决方案

Simply your code is not JPA compliant. The cause of problem is that you use Member as a part of your PK. The PK can only be made up of fields of the following Java types

  1. Primitives : boolean , byte , char , int , long , short
  2. java.lang : Boolean , Byte , Character , Integer , Long , Short , String , Enum , StringBuffer
  3. java.math : BigInteger java.sql : Date , Time , Timestamp
  4. java.util : Date , Currency, Locale, TimeZone, UUID
  5. java.net : URI, URL
  6. javax.jdo.spi : PersistenceCapable


This should work:

@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
}

Or the same with @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
}

相关文章