1

Is it possible to serialize a set of enums without a custom attribute converter?

@Entity
public class SomeEntity {

    @Id
    @GeneratedValue
    private Integer id;

    private Set<DayOfWeek> days;

}

The set of days has to be at the same table as SomeEntity.

I'm using Spring Data JPA 1.9 with Hibernate 4.3.1. Thanks.

User 2016
  • 73
  • 1
  • 4
  • Yes. so what happens when you try it? – Neil Stockton Nov 28 '15 at 08:24
  • I get this exception: org.hibernate.MappingException: Could not determine type for: java.util.Set, at table: some_entity, for columns: [org.hibernate.mapping.Column(days)] – User 2016 Nov 28 '15 at 08:33
  • I try to start application with ddl-auto=create and get the exception. – User 2016 Nov 28 '15 at 09:04
  • Yes, I mean "persist". I don't want to write a custom attribute converter for converting Set days to String and back. – User 2016 Nov 28 '15 at 09:18
  • @Lob will explicitly Java serialise the field into 1 column. The JPA implementation I use doesn't even need that since there is no other alternative way of persisting it other than Java serialised into a single column. Clearly you could use ElementCollection to put them in a join table – Neil Stockton Nov 28 '15 at 09:26
  • @Ruslan Pistriak, about no attribute converter: it's not related with the current issue, but are you aware that persisting java enum with jpa is quite fragile. By default, jpa will use the enum ordinal. Any change in the ordering of enum values will break the link with the content stored in the db. Enumerated has similar drawbacks.Then the JPA 2.1 Attribute Converter... – atao Nov 28 '15 at 10:56
  • @NeilStockton Usually I'm with you, but right here you missed that `Set` is _not_ `Serializable` (see my answer) ;-) – Tobias Liefke Nov 28 '15 at 18:34
  • @TobiasLiefke. A Set is not Serialized here, the instantiation is. So most likely HashSet (which is Serializable). The OP doesn't state the implementation being used. – Neil Stockton Nov 28 '15 at 19:12
  • @NeilStockton The instance is serialized, but the declared type of an property is used by Hibernate and any other JPA implementation to generate the mapping. – Tobias Liefke Nov 28 '15 at 19:22
  • Well clearly not. Since DataNucleus JPA can manage to persist it. – Neil Stockton Nov 28 '15 at 19:58
  • Interesting, because in that case it does not stick to the JPA spec, which explicitly states that _the type of the field or property_ needs to implement `Serializable` (_2.8 Mapping Defaults for Non-Relationship Fields or Properties_) - and further more: _It is an error if no annotation is present and none of the above rules apply._ – Tobias Liefke Nov 29 '15 at 19:58

2 Answers2

1

Hibernates stores all properties that declare a type that implements Serializable.

But the type of your days property is a Set, which does not extend Serializable. To store your set as serialized value you will need to declare a set class which implements Serializable - like most do. For example HashSet:

@Entity
public class SomeEntity {

    private HashSet<DayOfWeek> days;

}

You don't need any further annotations. This works for Enum and all other serializable elements.

But for a set of enums exists another option: Use an EnumSet, which stores the values into an integer column (every enum value is exactly one bit). See my answer here: JPA map collection of Enums

Community
  • 1
  • 1
Tobias Liefke
  • 8,637
  • 2
  • 41
  • 58
-1

Enum has Serializable as a Superinterface (see Javadoc API documentation for Enum)

So it shouldn't have any specific issue with Hibernate (which doesn't require to be serializable) or Spring Data JPA.

atao
  • 835
  • 6
  • 13