【问题标题】:Mapping EnumSet to mysql Set using JPA 2.1使用 JPA 2.1 将 EnumSet 映射到 mysql Set
【发布时间】:2017-02-09 12:20:32
【问题描述】:

我正在寻找将 EnumSet 存储在类型 set 的 mysql 列中的方法:

@Data
@Entity
@Table(name = "ENTITY_TABLE")
public class Entity implements Serializable {

  @Id
  @GeneratedValue
  @Column(nullable = false)
  @NotNull
  private String id;

  @Column(name = "types")
  private EnumSet<Type> types;

}

枚举类型定义如下:

public enum Type {
  TYPE1,
  TYPE2,
  TYPE3,
  TYPE4,
  TYPE5
}

并且表定义如下:

CREATE TABLE `ENTITY_TABLE` (
  `id` int(20) NOT NULL AUTO_INCREMENT,
  `types` set('TYPE1','TYPE2','TYPE3','TYPE4','TYPE5') DEFAULT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8

并在表格中插入:

INSERT INTO ENTITY_TABLE (types) VALUE ( 'TYPE1','TYPE2')

SET in mysql docs

【问题讨论】:

  • 我对mysql set type不熟悉。 JPA 中对 @Enumerated 类型的支持是针对单列值。
  • 鉴于您使用的是 JPA2.1,AttributeConverter 将是您的最佳选择。但是,您需要弄清楚在使用 JDBC 时如何使用 mysql set,这样您就知道在 AtrributeConverter 中要转换的内容和来自的内容

标签: java mysql jpa


【解决方案1】:

非常感谢!我不得不使用你在这里的一个稍微不同的版本。对我有用的是:

我有一个需要调整的权限枚举:

@Convert(converter = SetConverter.class)
@Column(name = "permission")
private EnumSet<Permission> permission;


//in a util and imported
...
@Converter
public static class SetConverter implements AttributeConverter<EnumSet<Permission>, String> {

    public String convertToDatabaseColumn(EnumSet<Permission> attribute) {
        StringBuilder sb = new StringBuilder();
        for (Permission c : attribute) { 
            sb.append(c + ",");
        }
        return sb.toString();
    }

    public EnumSet<Permission> convertToEntityAttribute(String dbData) {
        if (dbData == null) {
            dbData = "";
        }
        EnumSet<Permission> perm = EnumSet.of(Permission.DEFAULT); //default was a value I added.
        String[] persistencePermissions = StringUtils.trimAllWhitespace(dbData).toUpperCase().split(",");
        if (!StringUtils.isEmpty(StringUtils.trimAllWhitespace(dbData))) {
        try {
            for (String str : persistencePermissions) { 
            perm.add(Permission.valueOf(str));
        }}  
        catch (IllegalArgumentException IAE) {
            throw new Exception("INVALID_REQUEST");
        }}

        return perm;

    }

}

【讨论】:

  • 相反,您可以使用字符串连接器/拆分器。
  • 这样的字段怎么查询?
  • @AlessandroDionisi 这取决于您的设置。对于原始 MySQL,请参阅this SO this asnwer。在 Spring Data 术语中,扩展 CRUD interface: findByPermissionIn(EnumSet&lt;Permissions&gt; permissions); 理论上可以正常工作,可能甚至可以使用 Delta Spike。我之所以这么说是理论上的,是因为我修改了这段代码,并使用了多对多表的替代方法。
  • 我有一个非常相似的问题,使用此解决方案已解决,谢谢。我仍然必须意识到 EclipseLink 2.5.2 不喜欢转换器代码中的流。一旦我将它重构为使用旧的 for 循环,它就像一个魅力。
【解决方案2】:

Set 的默认 JPA 解决方案

@Data
@Entity
@Table(name = "ENTITY_TABLE")
public class Entity implements Serializable {

    @Id
    @GeneratedValue
    private String id;

    @ElementCollection
    @Enumerated(EnumType.STRING)
    @Column(name = "types")
    private Set<Type> types;

}

另一种可能性是AttributeConverter,但我从未尝试过使用 MySQL 设置。

@Data
@Entity
@Table(name = "ENTITY_TABLE")
public class Entity implements Serializable {

    @Id
    @GeneratedValue
    @Column(nullable = false)
    @NotNull
    private String id;

    @Convert(converter = SetConverter.class)
    @Column(name = "types")
    private EnumSet<Type> types;

}


@Converter
public class SetConverter implements AttributeConverter<EnumSet<Type>, String> {

    @Override
    public String convertToDatabaseColumn(EnumSet<Type> attribute) {
        // TODO Auto-generated method stub
        return null;
    }

    @Override
    public EnumSet<Type> convertToEntityAttribute(String dbData) {
        // TODO Auto-generated method stub
        return null;
    }

}

【讨论】:

  • 第一种方法将不起作用@ElementCollection 用于值不同的表但原始值。另外@ElementCollection 对 EnumSet 无效:org.hibernate.AnnotationException:非法尝试将非集合映射为@OneToMany,@ ManyToMany 或@CollectionOfElements
  • 你说得对,我忘了将 enumset 设置为正常集合。这是默认解决方案。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-23
  • 2011-01-25
  • 2011-05-24
  • 2012-04-06
  • 1970-01-01
相关资源
最近更新 更多