Skip to main content

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] [List Home]
Re: [eclipselink-dev] Question aboutEmbeddedAccessor#processEmbeddableClass()

Hi Guy!

Txs 4 the quick response!

So (I better repeat this to make sure I understood it correctly) the question is: should we store the aggregated EmbeddableAccessor once for each table, or once for every usage of @Embedded, correct?

As you've maybe read, I'm currently working on a prefix annotation for embedded classes. If this will be part of @Embedded or an own annotation doesn't imho change much, in any case we have add the m_prefix handling to the EmbeddedAccessor. So, I'm sure there is another way in the chain to add the prefix to the column names, but my gut feeling tells me that this would be much easier to implement if there is an EmbeddableAccessor for every Embedding. Including nested embeddings.

Btw, what about nested embeddings currently?
I did not debug through, but can you imagine a situation where we do also need the info parted in this case?

An example:

public class Price {
private BigDecimal amount;
private String     currency;

public class ListedPrice {
private int someValue;

private Price lPrice;

public class Purchase {
@Id @GeneratedValue private int id;

private ListedPrice listedPrice;

private Price soldPrice;

1.) Are there any valid annotations which may affect the fields? I know about the AttributeOverrides which has a special handling in EmbeddedAccessor, so this should not be a problem for @Embedding. But what happens if AttributeOverrides is being used inside a nested class (ListedPrice)?
2.) If so, may this be handled if we only have one EmbeddableAccessor per OwningDescriptor?

Humm, my brain is smoking, hope this post isn't getting too confusing ;)


And a few additional thoughts coming to my mind:
a) What would be the downside of storing the EmbeddableAccesor for each @Embedded usage? We have to store one for each entity anyway. Technically his would imho only have an effect if there are many embeddings of the same type in the same table. Logically it is simply a difference if an Accessor represents a 'database archetype' or a specific usage of this archetype. 
b) Could we split the EmbeddedAccessor in a 'static' part and a part for each embedding?
c) What about adding back-references to the actual EmbeddedAccessor for each processing step and stay with 1 EmbeddableAccessor (which then has to lookup varying parts from it's embedding)?

--- Guy Pelletier <guy.pelletier@xxxxxxxxxx> schrieb am Mi, 12.11.2008:

> Von: Guy Pelletier <guy.pelletier@xxxxxxxxxx>
> Betreff: Re: [eclipselink-dev] Question aboutEmbeddedAccessor#processEmbeddableClass()
> An: eclipselink-dev@xxxxxxxxxxx
> Datum: Mittwoch, 12. November 2008, 16:05
> 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
> (
> 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)
> /**
>  * 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
> eclipselink-dev mailing list
> eclipselink-dev@xxxxxxxxxxx

Back to the top