无法保存嵌入式实体Id。

3
我有一个名为 EcranChamp 的实体。
@Entity
@IdClass(EcranChampId.class)
public class EcranChamp {

@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "ecran")
Ecran ecran;


@Id
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "champ")
Champ champ;

...

并且EcranChampId

@Embeddable
public class EcranChampId implements Serializable  {    
private Champ champ;  
private Ecran ecran;
...

每次我尝试保存一个 EcranChamp 元素时,都会出现以下错误:

2018-09-25 12:15:42.889 WARN 14216 --- [nio-8092-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : 无法转换请求元素:org.springframework.beans.ConversionNotSupportedException: 无法将类型为 'java.lang.Long' 的属性值转换为 'com.kepler.portailclient.domain.model.Ecran' 所需的类型,属性为 'ecran'; 嵌套异常是 java.lang.IllegalStateException: 无法将类型为 'java.lang.Long' 的值转换为所需类型 'com.kepler.portailclient.domain.model.Ecran' 的属性 'ecran':找不到匹配的编辑器或转换策略 2018-09-25 12:15:42.889 WARN 14216 --- [nio-8092-exec-8] .w.s.m.s.DefaultHandlerExceptionResolver : 处理程序执行引起的已解决异常:org.springframework.beans.ConversionNotSupportedException: 无法将类型为 'java.lang.Long' 的属性值转换为 'com.kepler.portailclient.domain.model.Ecran' 所需的类型,属性为 'ecran'; 嵌套异常是 java.lang.IllegalStateException: 无法将类型为 'java.lang.Long' 的值转换为所需类型 'com.kepler.portailclient.domain.model.Ecran' 的属性 'ecran':找不到匹配的编辑器或转换策略


1
您使用了@IdClass注解来指定实体的id类为EcranChampId,因此必须将@Id字段的类型设置为EcramChampId。添加两个带有类型为EcranChamp@Id字段是不起作用的。 - Jesper
请提供一个解决此问题的方案,我会尝试它。 - Yagami Light
2个回答

2

尝试像这样:

@Entity
@Table(name = "<entity name>")
public class EcranChamp {

    @EmbeddedId
    @AttributeOverrides({ @AttributeOverride(name = "id_ecran", column = @Column(name = 
        "<column name>", nullable = false)),
    @AttributeOverride(name = "id_champ", column = @Column(name = "<column name>", nullable = false)) })
    EcranChampId id

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_ecran")
    Ecran ecran;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "id_champ")
    Champ champ; 
   //getters & setters 
 }   


@Embeddable
public class EcranChampId implements Serializable  {   
  @Column(name = "id_champ", nullable = false) 
  private Long id_champ; 
  @Column(name = "id_ecran", nullable = false)  
  private Long id_ecran; 
  //getters & setters 
}    

另外一个问题是如何避免创建两列,一列用于“ecran”,另一列用于“id_ecran”。 - Yagami Light
我不知道你的确切模型。但是你不需要在EcramChamp表中创建两个列,只需使用id_ecram字段即可。我想id_ecram是你的表中的PK/FK名称。编辑:我已经编辑了我的答案以更正。(@JoinColumn(name =“ id_ecran”)) - Seba López
我可以将可嵌入元素 private Long id_ecran; 替换为 private Ecran id_ecran; 吗? - Yagami Light

0

您应该使用@EmbeddedId注释。

请将您的EcranChampId类更改为以下内容:

@Embeddable
public class EcranChampId implements Serializable  {  

    @ManyToOne
    private Champ champ;

    @ManyToOne
    private Ecran ecran;

    //getters and setters
}

并将您的EcranChamp类更改为以下内容:

@Entity
@Table(name = "champ_has_ecran_table_name")
@AssociationOverrides({
    @AssociationOverride(name = "pk.champ", joinColumns = @JoinColumn(name = "champ_id"))
    @AssociationOverride(name = "pk.ecran", joinColumns = @JoinColumn(name = "ecran_id"))
})
public class EcranChamp {

    @EmbeddedId
    private EcranChampId pk;

    public EcranChamp() {
        pk = new EcranChampId();
    }

    public EcranChampId getPk() {
        return pk;
    }

    public void setPk(EcranChampId pk) {
        this.pk = pk;
    }

    @Transient
    public Champ getChamp() {
        return pk.getChamp();
    }

    public void setChamp(Champ champ) {
        pk.setChamp(champ);
    }

    @Transient
    public Ecran getEcran() {
        return pk.getEcran();
    }

    public void setChamp(Ecran ecran) {
        pk.setEcran(ecran);
    }
}

然后像这样使用:

public class Champ {

    @OneToMany(mappedBy = "pk.champ")
    private Collection<EcranChamp> ecranChamps;

    //getters and setters
}

此外,如果EcranChampEcranChampId没有其他字段,我建议您使用@ManyToMany注释而不是像这样使用EcranChamp类:
public class Champ {

    @ManyToMany
    @JoinTable(
        name = "champ_has_ecran_table_name",
        joinColumns = @JoinColumn(name = "champ_id", referencedColumnName = "id", nullable = false),
        inverseJoinColumns = @JoinColumn(name = "ecran_id", referencedColumnName = "id", nullable = false)
    )
    private Collection<Ecran> ecrans;

    //getters and setters
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接