* more details.
*
* Be careful while changing the order of processing.
*/
protected void processEmbeddableClass() {
EmbeddableAccessor accessor = getProject().getEmbeddableAccessor(getReferenceClassName());
if (accessor == null) {
// Before throwing an exception we must make one final check for
// an Embeddable annotation on the referenced class. At this point
// we know the referenced class was not tagged as an embeddable
// in a mapping file and was not included in the list of classes
// for this persistence unit. Its inclusion therefore in this
// persistence unit is through the use of an Embedded annotation
// or an embedded element within a known entity. Therefore validate
// that the reference class does indeed have an Embeddable
// annotation.
MetadataClass metadataClass = new MetadataClass(getReferenceClass());
if (metadataClass.isAnnotationNotPresent(Embeddable.class)) {
throw ValidationException.invalidEmbeddedAttribute(getJavaClass(), getAttributeName(), getReferenceClass());
} else {
accessor = new EmbeddableAccessor(metadataClass.getAnnotation(Embeddable.class), getReferenceClass(), getProject());
getProject().addEmbeddableAccessor(accessor);
}
}
if (accessor.isProcessed()) {
// We have already processed this embeddable class. Let's validate
// that it is not used in entities with conflicting access type
// when the embeddable doesn't have its own explicit setting. The
// biggest mistake that could occur otherwise is that FIELD
// processing 'could' yield a different mapping set then PROPERTY
// processing would. Do we really care? If both access types
// yielded the same mappings then the only difference would be
// how they are accessed and well ... does it really matter at this
// point? The only way to know if they would yield different
// mappings would be by processing the class for each access type
// and comparing the yield or some other code to manually inspect
// the class. I think this error should be removed since the spec
// states:
// "Embedded objects belong strictly to their owning entity, and
// are not sharable across persistent entities. Attempting to
// share an embedded object across entities has undefined
// semantics."
// I think we should assume the users know what they are are doing
// in this case (that is, if they opt to share an embeddable).
if (! accessor.hasAccess()) {
// We inherited our access from our owning entity.
if (! accessor.getDescriptor().getDefaultAccess().equals(getOwningDescriptor().getDefaultAccess())) {
throw ValidationException.conflictingAccessTypeForEmbeddable(accessor.getJavaClass(), accessor.usesPropertyAccess(), getOwningDescriptor().getJavaClass(), getOwningDescriptor().getClassAccessor().usesPropertyAccess());
}
}
} else {
// Need to set the owning descriptor on the embeddable class before
// we proceed any further in the processing.
accessor.setOwningDescriptor(getOwningDescriptor());
accessor.process();
accessor.setIsProcessed();
}
}