Hi,
Thanks for your answer.
My model is pretty complex so I tried to get rid of everything I assume is irrelevant concerning the problem.
If it is was not enough, I could provide you with the actual classes but there are quite a lot due to several levels of inheritance.
Here are the classes :
The class holding the map
Code:
@Entity
@Table(name = "diagnostic")
public class Diagnostic extends AnnotableObject<DiagnosticAnnotation, DiagnosticAttribute> {
private static final long serialVersionUID = 3825148115001055028L;
private Integer version = null;
protected Map<DiagnosticAttribute, DiagnosticAnnotation> annotations = new HashMap<DiagnosticAttribute, DiagnosticAnnotation>();
@Override
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
@Version
public Integer getVersion() {
return version;
}
@Override
//@DiagnosticMandatoryAnnotations => FAILING ON PERSISTENCE
@OneToMany(fetch = FetchType.EAGER, mappedBy = "entity", cascade = CascadeType.ALL/*, orphanRemoval = true*/)
@MapKey(name = "attribute")
public Map<DiagnosticAttribute, DiagnosticAnnotation> getAnnotations() {
return annotations;
}
public void setVersion(Integer version) {
this.version = version;
}
@Override
public void setAnnotations(Map<DiagnosticAttribute, DiagnosticAnnotation> annotations) {
this.annotations = annotations;
}
@Override
public void addAnnotation(DiagnosticAnnotation annotation) {
annotation.setEntity(this);
annotations.put(annotation.getAttribute(), annotation);
}
@Override
public void removeAnnotation(String name) {
DiagnosticAnnotation a = annotations.remove(new DiagnosticFreeAttribute(name));
a.setEntity(null);
}
}
The class used as a key for the map
Code:
@Entity
@Table(name = "attribute", uniqueConstraints = @UniqueConstraint(columnNames = {"type", "name"}))
@Inheritance(strategy = InheritanceType.SINGLE_TABLE)
@DiscriminatorColumn(name = "type", discriminatorType = DiscriminatorType.STRING)
public class DiagnosticAttribute<ENTITY extends Annotable<?, ?>> extends BaseObject implements Serializable {
private static final long serialVersionUID = -328834888742499071L;
protected String name;
@Override
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
public Long getId() {
return id;
}
@Column(length = 100, nullable = false)
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
The class used as a value for the map
Code:
@Entity
@Table(name = "eav_diagnostic")
public class DiagnosticAnnotation extends Annotation<Diagnostic, DiagnosticAttribute> implements Serializable {
private static final long serialVersionUID = -5180580885061582423L;
private Diagnostic entity = null;
private DiagnosticAttribute attribute = null;
@Override
@NotNull
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(nullable = false, updatable = false)
public Diagnostic getEntity() {
return super.getEntity();
}
@Override
@ManyToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(nullable = false, updatable = false)
public DiagnosticAttribute getAttribute() {
return super.getAttribute();
}
@Override
@NotNull
@Valid
@OneToOne(cascade = CascadeType.ALL, optional = false)
@JoinColumn(nullable = false, updatable = true)
public AnnotationValue<? extends DiagnosticAttribute> getValue() {
return value;
}
}
Here are the validation stuff :
Code:
@Target( { METHOD, FIELD, ANNOTATION_TYPE })
@Retention(RUNTIME)
@Constraint(validatedBy = DiagnosticMandatoryAnnotationsValidator.class)
@Documented
public @interface DiagnosticMandatoryAnnotations {
Class<? extends Payload>[] payload() default {};
Class<?>[] groups() default {};
String message() default "Il manque des données pour ce diagnostic";
String[] mandatoryNames() default { "diagnostic1", "diagnostic2", "dateDiagnostic2" };
}
Code:
public class DiagnosticMandatoryAnnotationsValidator implements ConstraintValidator<DiagnosticMandatoryAnnotations, Map<DiagnosticAttribute, DiagnosticAnnotation>> {
private String[] mandatoryNames;
public void initialize(DiagnosticMandatoryAnnotations constraintAnnotation) {
mandatoryNames = constraintAnnotation.mandatoryNames();
}
public boolean isValid(Map<DiagnosticAttribute, DiagnosticAnnotation> annotationMap, ConstraintValidatorContext constraintContext) {
for (String name: mandatoryNames) {
if (!annotationMap.containsKey(new DiagnosticFreeAttribute(name))){
return false;
}
}
return true;
}
}
Hope it helps to understand the problem.
Thanks