0

    public enum CameraType {
    
    CAMERA(false, false, "External lens ", ""),
    
    
    CameraType{
                boolean collector,
                boolean hidden,
                String description
            ) {
            this.collector = collector;
            this.granular = hidden;
            this.description = description;
            } // end ctor
           
           public void setHide(boolean hidden) {
               this.hide = hidden;
           }
    
    } // end enum

我有几个 CameraType 实例。

我有一个“隐藏”属性的设置器,在某些条件下设置为真或假。

现在我用 SecurityEntity 中的几个其他字段序列化 CameraType。

```
@Entity
@Table
public class Security {

 Few more fields...

@Enumerated(EnumType.STRING)
    @Column(nullable = false)
private CameraType cameraType

And other fields...
}
```

当我反序列化“隐藏”字段的值时,总是假的。如果我理解正确,在反序列化期间会调用 ctor 并分配默认值。

有没有办法在每个 CameraType 实例反序列化后保留“隐藏”字段的值(真或假)。

我正在使用 Postgres DB 10。

enter code here

请帮忙。我没有线索了。

4

2 回答 2

1

根据定义,枚举是固定集合的不可变元素。因此,要表示一个枚举值,您只需要它的名称。这正是 JPA 在序列化/反序列化期间所做的。

你试图违反规则。虽然 Java 允许您将枚举几乎视为普通对象,但 JPA 会根据它们应该是什么来处理它们。这就是您的代码无法正常工作的原因。

您可以:

  • 制作CameraType成一个类并将其序列化,或者
  • 分为CameraType两部分,例如enum CameraType(immutable) 和class CameraConfig(with all the mutable fields)
于 2021-03-26T18:21:34.950 回答
0

前一个答案是正确的:枚举必须是不可变的,将部分划分为不可变和可变数据是一个不错的选择。

这里有一个补充:使用枚举值进行数据库存储通常不是一个好的选择,因为当另一个开发人员决定重构枚举名称并且您正在从数据库中读取旧条目之后,您会遇到一个崩溃的应用程序......

所以我建议使用javax.persistence.AttributeConverter以特定的方式反序列化/序列化枚举并重命名保存方式。

这是一个非常简单的示例,其中包含一个名为的枚举MyDefinition

enum MyDefinition{

   ONE("def_one"),
   TWO"def_two"),
   THREE("def_three"),
   
   ;
   
   private String id;

   private MyDefinition(String id){
      this.id=id;
   }

   public String getId(){
      return id;
   }

    public static MyDefinition fromId(String id) {
        for (MyDefinition definition : MyDefinition.values()) {
            if (definition.id.equals(id)) {
                return definition;
            }
        }
        return null;
    }


}

这里是转换器:

import javax.persistence.AttributeConverter;
import javax.persistence.Converter;

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

    @Override
    public String convertToDatabaseColumn(MyDefinition attribute) {
       if (attribute == null){
           return null;}
       }
       return attribute.getId();
    }

    @Override
    public MyDefinition convertToEntityAttribute(String dbData) {
        return MyDefinition.fromId(dbData);
    }
 
 

所以我们可以使用数据库的ID。在读取旧数据时,重命名枚举名称将不再导致应用程序崩溃。

于 2021-07-27T12:52:01.923 回答