add dmp properties models

This commit is contained in:
Efstratios Giannopoulos 2024-01-15 15:06:50 +02:00
parent 9b079e4d4d
commit f6b7b6e00d
14 changed files with 497 additions and 18 deletions

View File

@ -1,20 +1,22 @@
package eu.eudat.commons.types.dmp;
import java.util.UUID;
public class DmpContactEntity {
String userId;
private UUID userId;
String firstName;
private String firstName;
String lastName;
private String lastName;
String email;
private String email;
public String getUserId() {
public UUID getUserId() {
return userId;
}
public void setUserId(String userId) {
public void setUserId(UUID userId) {
this.userId = userId;
}

View File

@ -4,6 +4,7 @@ import eu.eudat.commons.enums.DmpAccessType;
import eu.eudat.commons.enums.DmpStatus;
import eu.eudat.commons.enums.DmpVersionStatus;
import eu.eudat.commons.enums.IsActive;
import eu.eudat.model.dmpproperties.DmpProperties;
import java.time.Instant;
import java.util.List;
@ -26,7 +27,7 @@ public class Dmp {
private DmpVersionStatus versionStatus;
public static final String _versionStatus = "versionStatus";
private String properties;
private DmpProperties properties;
public static final String _properties = "properties";
private UUID groupId;
@ -115,11 +116,11 @@ public class Dmp {
this.status = status;
}
public String getProperties() {
public DmpProperties getProperties() {
return properties;
}
public void setProperties(String properties) {
public void setProperties(DmpProperties properties) {
this.properties = properties;
}

View File

@ -1,11 +1,16 @@
package eu.eudat.model.builder;
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.commons.JsonHandlingService;
import eu.eudat.commons.enums.EntityType;
import eu.eudat.commons.types.description.PropertyDefinitionEntity;
import eu.eudat.commons.types.dmp.DmpPropertiesEntity;
import eu.eudat.convention.ConventionService;
import eu.eudat.data.DmpDescriptionTemplateEntity;
import eu.eudat.data.DmpEntity;
import eu.eudat.model.*;
import eu.eudat.model.builder.descriptionpropertiesdefinition.PropertyDefinitionBuilder;
import eu.eudat.model.builder.dmpproperties.DmpPropertiesBuilder;
import eu.eudat.query.*;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.query.QueryFactory;
@ -30,16 +35,18 @@ public class DmpBuilder extends BaseBuilder<Dmp, DmpEntity> {
private final QueryFactory queryFactory;
private final BuilderFactory builderFactory;
private final JsonHandlingService jsonHandlingService;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public DmpBuilder(ConventionService conventionService,
QueryFactory queryFactory,
BuilderFactory builderFactory) {
BuilderFactory builderFactory, JsonHandlingService jsonHandlingService) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(DmpBuilder.class)));
this.queryFactory = queryFactory;
this.builderFactory = builderFactory;
this.jsonHandlingService = jsonHandlingService;
}
public DmpBuilder authorize(EnumSet<AuthorizationFlags> values) {
@ -77,13 +84,13 @@ public class DmpBuilder extends BaseBuilder<Dmp, DmpEntity> {
FieldSet dmpDescriptionTemplatesFields = fields.extractPrefixed(this.asPrefix(Dmp._dmpDescriptionTemplates));
Map<UUID, List<DmpDescriptionTemplate>> dmpDescriptionTemplatesMap = this.collectDmpDescriptionTemplates(dmpDescriptionTemplatesFields, data);
FieldSet propertiesFields = fields.extractPrefixed(this.asPrefix(Dmp._properties));
for (DmpEntity d : data) {
Dmp m = new Dmp();
if (fields.hasField(this.asIndexer(Dmp._id))) m.setId(d.getId());
if (fields.hasField(this.asIndexer(Dmp._label))) m.setLabel(d.getLabel());
if (fields.hasField(this.asIndexer(Dmp._version))) m.setVersion(d.getVersion());
if (fields.hasField(this.asIndexer(Dmp._status))) m.setStatus(d.getStatus());
if (fields.hasField(this.asIndexer(Dmp._properties))) m.setProperties(d.getProperties());
if (fields.hasField(this.asIndexer(Dmp._groupId))) m.setGroupId(d.getGroupId());
if (fields.hasField(this.asIndexer(Dmp._description))) m.setDescription(d.getDescription());
if (fields.hasField(this.asIndexer(Dmp._createdAt))) m.setCreatedAt(d.getCreatedAt());
@ -102,7 +109,10 @@ public class DmpBuilder extends BaseBuilder<Dmp, DmpEntity> {
if (dmpUsersMap != null && !dmpUsersMap.isEmpty() && dmpUsersMap.containsKey(d.getId())) m.setDmpUsers(dmpUsersMap.get(d.getId()));
if (descriptionsMap != null && !descriptionsMap.isEmpty() && descriptionsMap.containsKey(d.getId())) m.setDescriptions(descriptionsMap.get(d.getId()));
if (dmpDescriptionTemplatesMap != null && !dmpDescriptionTemplatesMap.isEmpty() && dmpDescriptionTemplatesMap.containsKey(d.getId())) m.setDmpDescriptionTemplates(dmpDescriptionTemplatesMap.get(d.getId()));
if (!propertiesFields.isEmpty() && d.getProperties() != null){
DmpPropertiesEntity propertyDefinition = this.jsonHandlingService.fromJsonSafe(DmpPropertiesEntity.class, d.getProperties());
m.setProperties(this.builderFactory.builder(DmpPropertiesBuilder.class).authorize(this.authorize).build(propertiesFields, propertyDefinition));
}
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));

View File

@ -0,0 +1,57 @@
package eu.eudat.model.builder.dmpproperties;
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.commons.types.dmp.DmpBlueprintValueEntity;
import eu.eudat.convention.ConventionService;
import eu.eudat.model.builder.BaseBuilder;
import eu.eudat.model.dmpproperties.DmpBlueprintValue;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
@Component("descriptionpropertiesdefinitionDmpBlueprintValuebuilder")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DmpBlueprintValueBuilder extends BaseBuilder<DmpBlueprintValue, DmpBlueprintValueEntity> {
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public DmpBlueprintValueBuilder(
ConventionService conventionService) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(DmpBlueprintValueBuilder.class)));
}
public DmpBlueprintValueBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<DmpBlueprintValue> build(FieldSet DmpBlueprintValues, List<DmpBlueprintValueEntity> data) throws MyApplicationException {
this.logger.debug("building for {} items requesting {} DmpBlueprintValues", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(DmpBlueprintValues).map(FieldSet::getFields).map(Set::size).orElse(0));
this.logger.trace(new DataLogEntry("requested DmpBlueprintValues", DmpBlueprintValues));
if (DmpBlueprintValues == null || data == null || DmpBlueprintValues.isEmpty())
return new ArrayList<>();
List<DmpBlueprintValue> models = new ArrayList<>();
for (DmpBlueprintValueEntity d : data) {
DmpBlueprintValue m = new DmpBlueprintValue();
if (DmpBlueprintValues.hasField(this.asIndexer(DmpBlueprintValue._fieldValue))) m.setFieldValue(d.getValue());
if (DmpBlueprintValues.hasField(this.asIndexer(DmpBlueprintValue._fieldId))) m.setFieldId(d.getFieldId());
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -0,0 +1,104 @@
package eu.eudat.model.builder.dmpContact;
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.commons.types.dmp.DmpContactEntity;
import eu.eudat.convention.ConventionService;
import eu.eudat.data.DmpUserEntity;
import eu.eudat.model.DmpUser;
import eu.eudat.model.User;
import eu.eudat.model.builder.BaseBuilder;
import eu.eudat.model.builder.UserBuilder;
import eu.eudat.model.dmpproperties.DmpContact;
import eu.eudat.query.UserQuery;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.data.query.QueryFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.fieldset.BaseFieldSet;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
import java.util.stream.Collectors;
@Component("dmpcontactbuilder")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DmpContactBuilder extends BaseBuilder<DmpContact, DmpContactEntity> {
private final BuilderFactory builderFactory;
private final QueryFactory queryFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public DmpContactBuilder(
ConventionService conventionService, BuilderFactory builderFactory, QueryFactory queryFactory) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(DmpContactBuilder.class)));
this.builderFactory = builderFactory;
this.queryFactory = queryFactory;
}
public DmpContactBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<DmpContact> build(FieldSet fields, List<DmpContactEntity> data) throws MyApplicationException {
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
this.logger.trace(new DataLogEntry("requested fields", fields));
if (fields == null || data == null || fields.isEmpty())
return new ArrayList<>();
//Not Bulk Build because is XML no interaction with db
FieldSet userFields = fields.extractPrefixed(this.asPrefix(DmpContact._user));
Map<UUID, User> userItemsMap = this.collectUsers(userFields, data);
List<DmpContact> models = new ArrayList<>();
for (DmpContactEntity d : data) {
DmpContact m = new DmpContact();
if (!userFields.isEmpty() && userItemsMap != null && userItemsMap.containsKey(d.getUserId())) m.setUser(userItemsMap.get(d.getUserId()));
if (fields.hasField(this.asIndexer(DmpContact._email))) m.setEmail(d.getEmail());
if (fields.hasField(this.asIndexer(DmpContact._firstName))) m.setFirstName(d.getFirstName());
if (fields.hasField(this.asIndexer(DmpContact._lastName))) m.setLastName(d.getLastName());
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
private Map<UUID, User> collectUsers(FieldSet fields, List<DmpContactEntity> data) throws MyApplicationException {
if (fields.isEmpty() || data.isEmpty())
return null;
this.logger.debug("checking related - {}", User.class.getSimpleName());
Map<UUID, User> itemMap;
if (!fields.hasOtherField(this.asIndexer(User._id))) {
itemMap = this.asEmpty(
data.stream().filter(x-> x.getUserId() != null).map(DmpContactEntity::getUserId).distinct().collect(Collectors.toList()),
x -> {
User item = new User();
item.setId(x);
return item;
},
User::getId);
} else {
FieldSet clone = new BaseFieldSet(fields.getFields()).ensure(User._id);
UserQuery q = this.queryFactory.query(UserQuery.class).authorize(this.authorize).ids(data.stream().filter(x-> x.getUserId() != null).map(DmpContactEntity::getUserId).distinct().collect(Collectors.toList()));
itemMap = this.builderFactory.builder(UserBuilder.class).authorize(this.authorize).asForeignKey(q, clone, User::getId);
}
if (!fields.hasField(User._id)) {
itemMap.forEach((id, item) -> {
if (item != null)
item.setId(null);
});
}
return itemMap;
}
}

View File

@ -0,0 +1,59 @@
package eu.eudat.model.builder.dmpproperties;
import eu.eudat.authorization.AuthorizationFlags;
import eu.eudat.commons.types.dmp.DmpPropertiesEntity;
import eu.eudat.convention.ConventionService;
import eu.eudat.model.builder.BaseBuilder;
import eu.eudat.model.dmpproperties.DmpProperties;
import gr.cite.tools.data.builder.BuilderFactory;
import gr.cite.tools.exception.MyApplicationException;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.*;
@Component("dmppropertiesbuilder")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DmpPropertiesBuilder extends BaseBuilder<DmpProperties, DmpPropertiesEntity> {
private final BuilderFactory builderFactory;
private EnumSet<AuthorizationFlags> authorize = EnumSet.of(AuthorizationFlags.None);
@Autowired
public DmpPropertiesBuilder(
ConventionService conventionService, BuilderFactory builderFactory) {
super(conventionService, new LoggerService(LoggerFactory.getLogger(DmpPropertiesBuilder.class)));
this.builderFactory = builderFactory;
}
public DmpPropertiesBuilder authorize(EnumSet<AuthorizationFlags> values) {
this.authorize = values;
return this;
}
@Override
public List<DmpProperties> build(FieldSet fields, List<DmpPropertiesEntity> data) throws MyApplicationException {
this.logger.debug("building for {} items requesting {} fields", Optional.ofNullable(data).map(List::size).orElse(0), Optional.ofNullable(fields).map(FieldSet::getFields).map(Set::size).orElse(0));
this.logger.trace(new DataLogEntry("requested fields", fields));
if (fields == null || data == null || fields.isEmpty())
return new ArrayList<>();
//Not Bulk Build because is XML no interaction with db
FieldSet dmpBlueprintValuesFields = fields.extractPrefixed(this.asPrefix(DmpProperties._dmpBlueprintValues));
List<DmpProperties> models = new ArrayList<>();
for (DmpPropertiesEntity d : data) {
DmpProperties m = new DmpProperties();
if (!dmpBlueprintValuesFields.isEmpty() && d.getDmpBlueprintValues() != null) m.setDmpBlueprintValues(this.builderFactory.builder(DmpBlueprintValueBuilder.class).authorize(this.authorize).build(dmpBlueprintValuesFields, d.getDmpBlueprintValues()));
models.add(m);
}
this.logger.debug("build {} items", Optional.of(models).map(List::size).orElse(0));
return models;
}
}

View File

@ -3,6 +3,7 @@ package eu.eudat.model.censorship;
import eu.eudat.authorization.Permission;
import eu.eudat.convention.ConventionService;
import eu.eudat.model.Dmp;
import eu.eudat.model.censorship.dmpproperties.DmpPropertiesCensor;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.data.censor.CensorFactory;
import gr.cite.tools.fieldset.FieldSet;
@ -48,5 +49,7 @@ public class DmpCensor extends BaseCensor {
this.censorFactory.censor(UserCensor.class).censor(creatorFields, userId);
FieldSet doisFields = fields.extractPrefixed(this.asIndexerPrefix(Dmp._entityDois));
this.censorFactory.censor(EntityDoiCensor.class).censor(doisFields, userId);
FieldSet propertiesFields = fields.extractPrefixed(this.asIndexerPrefix(Dmp._properties));
this.censorFactory.censor(DmpPropertiesCensor.class).censor(propertiesFields, userId);
}
}

View File

@ -0,0 +1,39 @@
package eu.eudat.model.censorship.dmpproperties;
import eu.eudat.authorization.Permission;
import eu.eudat.convention.ConventionService;
import eu.eudat.model.censorship.BaseCensor;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component("dmpblueprintvaluecensor")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DmpBlueprintValueCensor extends BaseCensor {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpBlueprintValueCensor.class));
protected final AuthorizationService authService;
public DmpBlueprintValueCensor(ConventionService conventionService,
AuthorizationService authService) {
super(conventionService);
this.authService = authService;
}
public void censor(FieldSet fields, UUID userId) {
logger.debug(new DataLogEntry("censoring fields", fields));
if (fields == null || fields.isEmpty())
return;
this.authService.authorizeForce(Permission.BrowseDmp);
}
}

View File

@ -0,0 +1,48 @@
package eu.eudat.model.censorship.dmpproperties;
import eu.eudat.authorization.Permission;
import eu.eudat.convention.ConventionService;
import eu.eudat.model.censorship.BaseCensor;
import eu.eudat.model.censorship.DmpCensor;
import eu.eudat.model.censorship.UserCensor;
import eu.eudat.model.dmpproperties.DmpContact;
import eu.eudat.model.dmpproperties.DmpProperties;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.data.censor.CensorFactory;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component("dmpcontactcensor")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DmpContactCensor extends BaseCensor {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpContactCensor.class));
protected final AuthorizationService authService;
protected final CensorFactory censorFactory;
public DmpContactCensor(ConventionService conventionService,
AuthorizationService authService, CensorFactory censorFactory) {
super(conventionService);
this.authService = authService;
this.censorFactory = censorFactory;
}
public void censor(FieldSet fields, UUID userId) {
logger.debug(new DataLogEntry("censoring fields", fields));
if (fields == null || fields.isEmpty())
return;
this.authService.authorizeForce(Permission.BrowseDmp);
FieldSet userFields = fields.extractPrefixed(this.asIndexerPrefix(DmpContact._user));
this.censorFactory.censor(UserCensor.class).censor(userFields, userId);
}
}

View File

@ -0,0 +1,48 @@
package eu.eudat.model.censorship.dmpproperties;
import eu.eudat.authorization.Permission;
import eu.eudat.convention.ConventionService;
import eu.eudat.model.censorship.BaseCensor;
import eu.eudat.model.dmpproperties.DmpProperties;
import gr.cite.commons.web.authz.service.AuthorizationService;
import gr.cite.tools.data.censor.CensorFactory;
import gr.cite.tools.fieldset.FieldSet;
import gr.cite.tools.logging.DataLogEntry;
import gr.cite.tools.logging.LoggerService;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.config.ConfigurableBeanFactory;
import org.springframework.context.annotation.Scope;
import org.springframework.stereotype.Component;
import java.util.UUID;
@Component("dmppropertiescensor")
@Scope(value = ConfigurableBeanFactory.SCOPE_PROTOTYPE)
public class DmpPropertiesCensor extends BaseCensor {
private static final LoggerService logger = new LoggerService(LoggerFactory.getLogger(DmpPropertiesCensor.class));
protected final AuthorizationService authService;
protected final CensorFactory censorFactory;
public DmpPropertiesCensor(ConventionService conventionService,
AuthorizationService authService,
CensorFactory censorFactory) {
super(conventionService);
this.authService = authService;
this.censorFactory = censorFactory;
}
public void censor(FieldSet fields, UUID userId) {
logger.debug(new DataLogEntry("censoring fields", fields));
if (fields == null || fields.isEmpty())
return;
this.authService.authorizeForce(Permission.BrowseDmp);
FieldSet dmpBlueprintValuesFields = fields.extractPrefixed(this.asIndexerPrefix(DmpProperties._dmpBlueprintValues));
this.censorFactory.censor(DmpBlueprintValueCensor.class).censor(dmpBlueprintValuesFields, userId);
FieldSet contactsFields = fields.extractPrefixed(this.asIndexerPrefix(DmpProperties._contacts));
this.censorFactory.censor(DmpContactCensor.class).censor(contactsFields, userId);
}
}

View File

@ -0,0 +1,27 @@
package eu.eudat.model.dmpproperties;
import java.util.UUID;
public class DmpBlueprintValue {
private UUID fieldId;
public static final String _fieldId = "fieldId";
private String fieldValue;
public static final String _fieldValue = "fieldValue";
public UUID getFieldId() {
return fieldId;
}
public void setFieldId(UUID fieldId) {
this.fieldId = fieldId;
}
public String getFieldValue() {
return fieldValue;
}
public void setFieldValue(String fieldValue) {
this.fieldValue = fieldValue;
}
}

View File

@ -0,0 +1,49 @@
package eu.eudat.model.dmpproperties;
import eu.eudat.model.User;
public class DmpContact {
private User user;
public static final String _user = "user";
private String firstName;
public static final String _firstName = "firstName";
private String lastName;
public static final String _lastName = "lastName";
private String email;
public static final String _email = "email";
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
}

View File

@ -0,0 +1,31 @@
package eu.eudat.model.dmpproperties;
import java.util.List;
public class DmpProperties {
private List<DmpBlueprintValue> dmpBlueprintValues;
public static final String _dmpBlueprintValues = "dmpBlueprintValues";
private List<DmpContact> contacts;
public static final String _contacts = "contacts";
public List<DmpBlueprintValue> getDmpBlueprintValues() {
return dmpBlueprintValues;
}
public void setDmpBlueprintValues(List<DmpBlueprintValue> dmpBlueprintValues) {
this.dmpBlueprintValues = dmpBlueprintValues;
}
public List<DmpContact> getContacts() {
return contacts;
}
public void setContacts(List<DmpContact> contacts) {
this.contacts = contacts;
}
}

View File

@ -10,22 +10,23 @@ import org.springframework.stereotype.Component;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;
public class DmpContactPersist {
String userId;
private UUID userId;
String firstName;
private String firstName;
String lastName;
private String lastName;
String email;
private String email;
public String getUserId() {
public UUID getUserId() {
return userId;
}
public void setUserId(String userId) {
public void setUserId(UUID userId) {
this.userId = userId;
}