枚举值不会作为EnumType.STRING保留,而是作为子实体

时间:2016-12-13 19:00:40

标签: spring hibernate jpa

在使用Spring JPA时,枚举值不会作为EnumType.STRING保留,而是作为子实体的EnumType.ORDINAL值保留

我有Employee实体,它有名称,ENUM字段和地址(子)实体的一对多关联。保存Employee实体时,父实体上的枚举字段将保持为String(如预期的那样),但子实体中的枚举字段将作为序数值保留,尽管我在父实体和子实体中使用了@Enumerated EnumType.STRING

我的实体

Employee.java

@Entity
@Table(name = "employee", schema = "schema_emp")
public class Employee {

    public enum Status {
        PROJECT,
        BENCH;
    }
    private String _name;   
    private Status _status;
    private Map<EmployeeAddress.Type, EmployeeAddress> _addresses;

    protected Employee () {
    }

    @Column(name = "employee_name", nullable = false)
    public String getName() {
        return this._name;
    }

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

    @Column(name = "status_text", nullable = false)
    @Enumerated(EnumType.STRING)
    public Status getStatus() {
        return this._status;
    }

    protected void setStatus(Status status) {
        this._status= status;
    }

    @ElementCollection(fetch = FetchType.EAGER)
    @MapKeyColumn(name = "address_type_name")
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "employee", cascade = CascadeType.ALL, orphanRemoval = true)
    public Map<EmployeeAddress.Type, EmployeeAddress> getAddresses() {
        return _addresses;
    }

    public void setAddresses(Map<EmployeeAddress.Type, EmployeeAddress> addresses) {
        _addresses = addresses;
    }
}

EmployeeAddress.java    

@Entity
@Table(name = "employee_address", schema = "schema_emp")
public class EmployeeAddress {

public enum Type {
        PRIMARY,
        BILLING,
        MAILING,
        SHIPPING;
    }

private Employee _employee;
private Type _type;
private String _line1;

protected EmployeeAddress() {
}

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "employee_id", nullable = false)
public Employee getEmployee() {
return _employee;
}

public void setEmployee(Employee employee) {
        _employee = employee ;
}

@Column(name = "address_type_name", nullable = false)
@Enumerated(EnumType.STRING)
@NotNull
public Type getType() {
    return _type;
}

public void setType(Type type) {
        _type = type;
}

@Column(name = "address_line_1")
public String getLine1() {
    return _line1;
}

public void setLine1(String line1) {
        _line1 = line1;
}

}

My service method 

Employee entity = populateEntity(resource);
new Employee .Builder<>().buildAddresses(resource.getAddresses(), entity);
return _repository.saveAndFlush(entity);

当我检查数据库时,在Employee表中按预期创建了一行,并在employee_address表中创建了适当的行数

在employee表中,status_text字段为ACTIVE但是 在employee_address表中,address_type_name是0和3(即ORDINAL值)

那么如何将ENUM值作为String存储在子表中,即employee_address

1 个答案:

答案 0 :(得分:0)

一种解决方案是定义Converter类并将其自动应用于子实体

中的类型字段

转换器代码:

@Converter(autoApply = true)
public class AddressTypeConverter implements AttributeConverter<Type, String> {

    @Override
    public String convertToDatabaseColumn(Type type) {
            return type.name();
        }

    @Override
    public Type convertToEntityAttribute(String typeStr) {
        return Type.valueOf(typeStr);
    }
}

及其在EmployeeAddress类中的用法:

@Column(name = "address_type_name", nullable = false)
@Convert(converter = AddressTypeConverter.class)
@NotNull
public Type getType() {
    return _type;
}