报错:nested exception is org.hibernate.MappingException: Composite-id class must implement Serializable: cn.edkso.product.entity.ProductCategory

SpringBootJPA (Hibernate)报错

报错截图

file

错误原因

我的实体类,不小心多出来个主键的注解,使用联合主键时,bean类必须序列化

import java.io.Serializable;
public classBean implements Serializable {
}

file

解决方案

去掉多余的主键注解

关于必须序列化的原因(这是我查到的,并不特别理解,希望有大佬指出!!)

hibernate处理复合主键映射是基于这样一种做法:把目标类中所有主键关联属性抽出来,单独写成一个类(我暂且叫它主键类),目标类就只需持有主键类对象,而不必再包含各个主键属性;在映射文件中使用标签来配置主键对象并指出关联属性,普通属性照常配置;hibernate只会创建一张表在,并且把主键设置为主键类各属性的联合主键,存储和加载数据时,会自然的把关联对象各属性跟表中的主键字段对应起来。在这个操作过程中,它要求主键类必须是序列化的,并且要覆盖equals方法,最好覆盖hashCode方法

两个或多个字段组成的主键,我们叫联合主键。在面向对象中,我们用JPA怎么定义这种情况呢?
怎么定义联合主键?用面向对象的思想来思考的话,联合主键里的复合主键(字段),可以把它看成一个整体,然后采用一个主键类来描述这个复合主键的字段。

关于联合主键类,大家一定要遵守以下几点JPA规范:
必须提供一个public的无参数构造函数。
必须实现序列化接口。
必须重写hashCode()和equals()这两个方法。这两个方法应该采用复合主键的字段作为判断这个对象是否相等的。
联合主键类的类名结尾一般要加上PK两个字母代表一个主键类,不是要求而是一种命名风格。

案例:

//ArtLinePK.java
//Java代码
package cn.itcast.bean;   

import java.io.Serializable;   

import javax.persistence.Column;   
import javax.persistence.Embeddable;   

@Embeddable  
//这个注解代表ArtLinePK这个类是用在实体里面,告诉JPA的实现产品:在实体类里面只是使用这个类定义的属性。   
//简单的理解为:ArtLinePK里的属性可以看成是ArtLine类里的属性,好比ArtLinePK的属性就是在ArtLine里定义的。   
public class ArtLinePK implements Serializable{   
    private String startCity;   
    private String endCity;   

    public ArtLinePK() {   
    }   

    public ArtLinePK(String startCity, String endCity) {   
        this.startCity = startCity;   
        this.endCity = endCity;   
    }   

    @Column(length=3)   
    public String getStartCity() {   
        return startCity;   
    }   

    public void setStartCity(String startCity) {   
        this.startCity = startCity;   
    }   

    @Column(length=3)   
    public String getEndCity() {   
        return endCity;   
    }   

    public void setEndCity(String endCity) {   
        this.endCity = endCity;   
    }   

    @Override  
    public int hashCode() {   
        final int prime = 31;   
        int result = 1;   
        result = prime * result + ((endCity == null) ? 0 : endCity.hashCode());   
        result = prime * result   
                + ((startCity == null) ? 0 : startCity.hashCode());   
        return result;   
    }   

    @Override  
    public boolean equals(Object obj) {   
        if (this == obj)   
            return true;   
        if (obj == null)   
            return false;   
        if (getClass() != obj.getClass())   
            return false;   
        final ArtLinePK other = (ArtLinePK) obj;   
        if (endCity == null) {   
            if (other.endCity != null)   
                return false;   
        } else if (!endCity.equals(other.endCity))   
            return false;   
        if (startCity == null) {   
            if (other.startCity != null)   
                return false;   
        } else if (!startCity.equals(other.startCity))   
            return false;   
        return true;   
    }   

}  

//这个联合主键类,应该作为实体类的一个主键(实体标识符,id)。
//ArtLine.java
//Java代码 

package cn.itcast.bean;   

import javax.persistence.Column;   
import javax.persistence.EmbeddedId;   
import javax.persistence.Entity;   

@Entity  
public class ArtLine {   
    private ArtLinePK id;   //用面向对象的思想去思考的话,这个复合主键看成一个整体,由复合主键类ArtLinePK来描述。   
    private String name;   

    public ArtLine() {   
    }   

    public ArtLine(ArtLinePK id) {   
        this.id = id;   
    }   

    public ArtLine(String startCity, String endCity, String name) {   
        this.id = new ArtLinePK(startCity, endCity);   
        this.name = name;   
    }   

    @EmbeddedId //按照JPA规范要求,[email protected]   
    [email protected] 这个注解用于标注id这个属性为实体的标识符,因为我们使用的是复合主键类,[email protected]标志实体标识符的注解。   
    public ArtLinePK getId() {   
        return id;   
    }   

    public void setId(ArtLinePK id) {   
        this.id = id;   
    }   

    @Column(length=20)   
    public String getName() {   
        return name;   
    }   

    public void setName(String name) {   
        this.name = name;   
    }   
}  

我们的复合主键类,目前为止,已经定义好了。

版权声明:
作者:十下
链接:http://blog.edkso.cn/?p=966
来源:十下博客
文章版权归作者所有,未经允许请勿转载。

THE END
分享
二维码
打赏
< <上一篇
下一篇>>