I'm trying to persist an entity that has a Map of Objects to Enum into a Google App Engine datastore. The entity classes are annotated using JPA.
Event class
import com.google.appengine.datanucleus.annotations.Unowned;
import com.google.appengine.api.datastore.Key;
import java.util.Map;
import javax.persistence.*;
import lombok.Builder;
import lombok.Data;
@Entity
@Builder
public @Data class Event {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;
// I want a map belonging to event in order to query a particular user whether he confirmed his participation in the event
// All addressees are initially present in this map with response set to UNDEFINED
// If user has received and read notification, than the response is updated to YES, NO, or MAYBE
@Unowned
@ElementCollection
@CollectionTable(name = "user_response")
@MapKeyJoinColumn(name = "user_id")
@Enumerated
@Column(name = "response")
private Map<User, Response> addressees;
}
Response class
public enum Response {
UNDEFINED, YES, NO, MAYBE
}
I haven't defined any references in User
class to this map. It's a unidirectional relationship.
User class
@Entity
public @Data class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Key key;
}
The Event.addressees
column seems pretty tricky. So I ran my test to check if everything was working correctly. Well, it was not. I got an exception when I tried to save an Event
entity to the datastore:
java.lang.IllegalArgumentException: addressees: Response is not a supported property type.
at com.google.appengine.api.datastore.DataTypeUtils.checkSupportedSingleValue(DataTypeUtils.java:235)
at com.google.appengine.api.datastore.DataTypeUtils.checkSupportedValue(DataTypeUtils.java:199)
at com.google.appengine.api.datastore.DataTypeUtils.checkSupportedValue(DataTypeUtils.java:173)
at com.google.appengine.api.datastore.DataTypeUtils.checkSupportedValue(DataTypeUtils.java:148)
at com.google.appengine.api.datastore.PropertyContainer.setProperty(PropertyContainer.java:101)
According to DataNucleus Enum is a persistable data type by default. So I don't understand why I get the error message saying "Response is not a supported property type"
.
I suspected that the problem was with the User class. Maybe the association from Event to Users was not enough, and User should also have an association to Events. So I've added the events
field to User as follows:
@Unowned
@ElementCollection
@CollectionTable(name = "user_event_responses")
@ManyToMany(mappedBy="addressees", targetEntity = Event.class)
@MapKeyJoinColumn
@Enumerated
@Column(name = "response")
private Map<Event, Response> events;
It didn't work anyway. Then I've read similar questions, and found no quick answer.
Please, show me an example of many-to-many relationship with an extra column in DataNucleus / JPA!