|  Hi Mark,
 Happy to hear you're enjoying 
working with the code.
 
 What you have pointed out is indeed a problem and 
is problamatic for a number of use cases. See the following bug 
(https://bugs.eclipse.org/bugs/show_bug.cgi?id=250144)
 
 The notion of the 
owning descriptor should remain however (e.g. an id field defined on an 
embeddable requires setting metadata on the actual owning entity) , but the 
problem as you have pointed out is that the embeddable class is only processed 
once from the first entity that references it. So this is incorrect. The 
embeddable class should likely be cloned (similarly as we do with mapped 
superclasses) and re-processed using the context or each owning descriptor. 
Note, the whole class likely will not need to be re-processed, likely only the 
accessors and again you'll have to be careful as to which accessors gets 
re-processed since you don't want all the metadata from your embeddable class 
stored on the owning descriptor.
 
 See the reloadMappedSuperclass 
method from ORMetadata. Notice, it clones a mapped superclass by reloading 
it from XML. In your case you would have to handle the case where the Embeddable 
was not loaded from XML (the accessible object will not have an associated 
entity mappings object) and you'd likely just have to create a new instance 
of the EmbeddableAccessor. I've just recently built a similar method for 
Entities (in my current work for TABLE_PER_CLASS support, see 
below)
 
 /**
 * INTERNAL:
 * This 
method should be called to reload an entity (that was either
 * loaded 
from XML or an annotation) as a way of cloning it. This is needed
 * 
when we process TABLE_PER_CLASS inheritance. We must process the 
parent
 * classes for every subclasses descriptor. The processing is 
similar to
 * that of processing a mapped superclass, in that we process 
the parents
 * with the subclasses context (that is, the descriptor we 
are given).
 */
 protected EntityAccessor reloadEntity(EntityAccessor 
entity, MetadataDescriptor descriptor) {
 if 
(m_accessibleObject.getEntityMappings() == null) {
 // Create a new EntityAccesor.
 EntityAccessor entityAccessor = new 
EntityAccessor(entity.getAnnotation(), entity.getJavaClass(), 
entity.getProject());
 // Things we care 
about ...
 entityAccessor.setDescriptor(descriptor);
 entityAccessor.getDescriptor().setDefaultAccess(entity.getDescriptor().getDefaultAccess());
 return entityAccessor;
 } else 
{
 return 
m_accessibleObject.getEntityMappings().reloadEntity(entity, 
descriptor);
 }
 }
 
 Hope this helps!   Cheers, Guy 
 ----- Original Message -----
 From: "Mark Struberg" 
<struberg@xxxxxxxx>
 To: <eclipselink-dev@xxxxxxxxxxx>
 Sent: 
Wednesday, November 12, 2008 6:04 AM
 Subject: [eclipselink-dev] Question 
aboutEmbeddedAccessor#processEmbeddableClass()
 
 
 Hi!
 
 I've read 
through the eclipselink sources and like to add a few 
features.
 
 Generally, I'd to say that it is a really well done and _very_ 
readable source! I did look at the sources for only 2 evenings now (and I really 
enjoyed digging into it), so don't be rude if I completely misinterpreted/not 
understood something yet :)
 
 There's a point in the EmbeddedAccesor which 
I do not understand:
 
 In the function processEmbeddableClass(), a 'cached' 
EmbeddedAccessor instance is retrieved (line # 
299)
 EmbeddableAccessor accessor = 
getProject().getEmbeddableAccessor(getReferenceClassName());
 
 So I'll get 
the same EmbeddableAccessor instance for EVERY embedding of the same 
class.
 
 A bit later in the source (line # 349), this EmbeddableAccessor 
will be filled with the 
OwningDescriptor:
 accessor.setOwningDescriptor(getOwningDescriptor());
 
 BUT: imho the owning 
descriptor may be different for each @Embedded !?
 
 In praxis this means, 
that the EmbeddableAccessor always points to the Table-Descriptor of the 'first' 
occurence (which one this ever may be -> random generator?), and the other 
ones may simply contain wrong values.
 
 My 
example:
 
 @Embeddable
 public class Price {
 private BigDecimal 
amount;
 private String     
currency;
 }
 
 @Entity
 public class Purchase 
{
 @Id
 @GeneratedValue
 private int id;
 
 @Embedded(prefix = 
"N_")
 private Price netPrice;
 
 @Embedded(prefix = "G_")
 private 
Price grossPrice;
 }
 
 @Entity
 public class OtherUseOfPrice 
{
 @Id
 @GeneratedValue
 private int id;
 
 @Embedded(prefix = 
"O_")
 private Price otherPrice;
 }
 
 In the debugger I got the 
following memory addresses:
 
 O_ id=40 accessor=98 getowningDescriptor()= 
45
 N_ id=101 accessor=98 getowningDescriptor()= 102
 G_ id=116 accessor=98 
getowningDescriptor()= 102
 
 And as expected, the accessor of the 
embeddings of netPrice (N_) and grossPrice (G_) point to the wrong 
m_owningDescriptor 45 instead of the correct 102
 
 Does this have any 
impact on the result? If not, we also could remove the owningDescriptor from the 
EmbeddableAccessor, otherwise it may be a source of problems, 
isn't?
 
 
 
 
 _______________________________________________
 eclipselink-dev mailing 
list
 eclipselink-dev@xxxxxxxxxxx
 https://dev.eclipse.org/mailman/listinfo/eclipselink-dev
 |