You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@openjpa.apache.org by Michael Dick <mi...@gmail.com> on 2011/06/29 15:55:37 UTC

Metamodel generates ListAttribute for arrays instead of SingularAttribute

Does anyone remember why we generate a ListAttribute for arrays instead of a
SingularAttribute?

In section 6.2.1.1. the JPA spec indicates that we should generate a
SingularAttribute for every non-collection-valued field, and a
Collection|Set|List Attribute for their respective types.

Generating a ListAttribute for a @PersistentCollection makes sense, but
generating it for all arrays, doesn't look quite right. AFAICT this code was
added under OPENJPA-1013, but that was a general development task. There
weren't any clues to the motivation for this part of the change, except that
one of the testcases does use a @PersistentCollection.

At any rate, this seems wrong to me, but before I start modifying code I
wanted to make sure I'm not missing something.

Thanks,
-mike

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Craig L Russell <cr...@oracle.com>.
On Jun 29, 2011, at 4:24 PM, Michael Dick wrote:

> Let me try to reel this one back in, I think some signal has gotten  
> lost.

I agree.
>
> The example I'm concerned with is a byte array. The problem I'm  
> trying to
> solve is that of compatibility with canonical metamodel classes.

There are several array classes that we might consider separately.  
 From a modeling perspective, a byte[ ] is similar to a String, so I'd  
expect it to be treated as a SingularAttribute.

Similarly, char[ ] is the next best thing to a String, and I'd expect  
it to be treated as a SingularAttribute.

But when you go beyond byte[ ] and char[ ], you get into types that I  
would consider second class container types.

short[ ], int[ ], long[ ], double[ ], float[ ], Integer[ ], Short[ ],  
Long[ ], BigDecimal[ ], BigInteger[ ], Employee[ ], etc. are most  
similar to UnmodifiableList reference types that I'd model as  
Collections.

Craig
>
> For example, I would expect the canonical metamodel classes  
> generated by
> Dali to work with OpenJPA. As I understand it, they do not work  
> because Dali
> generates a SingularAttribute for byte arrays.
>
> My read of the spec is that using a SingularAttribute is correct.  
> Collection
> valued fields are generally used to refer to relationships. This can  
> be
> extended to encompass @PersistentCollections, but shouldn't apply to  
> a byte
> array.
>
> While I understand your opinion that the spec came second, I think  
> that the
> point of the spec is to address compatibility issues like this one.
>
> -mike
>
> On Wed, Jun 29, 2011 at 1:41 PM, Pinaki Poddar <pp...@apache.org>  
> wrote:
>
>> Arrays are specialized Lists. Or Lists are specialized Arrays. Like
>> Rectangle
>> is a specialized Square. Or Square is a specialized Rectangle. Formal
>> language inheritance concept does not pin this either way but  
>> allows one to
>> consider either view.
>>
>> OpenJPA had so far modeled Array as second-class container in a  
>> consistent
>> manner as it did for java.util.Collection and its subtypes. I  
>> support such
>> modeling. It also has an extra makeDirty() because of technical  
>> complexity
>> of tracking changes in second-class containers w.r.t Arrays.
>>
>> From that viewpoint of maintaining continuity of design principles  
>> of the
>> original authors, the modeling of Array as List is correct, imo.
>>
>> Primitive collection requires different treatment. That is why JPA  
>> 2.0 had
>> to annotate @ElementCollection to distinguish from reference  
>> collection.
>> Let
>> us keep that aside for the time being.
>>
>> Now on why "X spec says so..." is a weak argument
>>
>> Specs are combined voices of you and I and all the people who are  
>> brave and
>> crazy enough to explore new ideas in open source projects. Specs  
>> follow
>> Open
>> Source. Not the other way around. Open Source is the playground where
>> technical debate (as we are now engaged in) takes place, where new  
>> ideas
>> emerge. If the ideas are solid and the democracy of users accept it  
>> -- then
>> the spec of future years will adopt it.
>>
>> As far as persistence of Arrays is concerned -- JPA spec says almost
>> nothing. The onus is on us as open source developers who have to  
>> figure out
>> what is a *good* way. If the users accept it -- then we did a good  
>> job and
>> we can take our view to the experts of spec committee to make that  
>> view
>> part
>> of a standard. Today where JPA spec stands is a testimonial to such  
>> effort
>> by Hibernate or Kodo and many others who built their software  
>> *without* a
>> spec guiding them what to do or what is the "right" way. In fact,  
>> it is
>> they
>> who made today's JPA spec possible. That is why I said : "X spec says
>> so..."
>> is a weak argument in a open source context.
>>
>>
>>
>>
>>
>> -----
>> Pinaki
>> --
>> View this message in context:
>> http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6530220.html
>> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>>

Craig L Russell
Architect, Oracle
http://db.apache.org/jdo
408 276-5638 mailto:Craig.Russell@oracle.com
P.S. A good JDO? O, Gasp!


Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Michael Dick <mi...@gmail.com>.
I'm not sure what Dali does in this specific case.

I think our answer will largely depend on whether Bar is serializable. If
Bar is not serializable we will be unable to map field a (I'm not sure about
b - seems to just be ignored). If Bar is serializable we'll map the array as
a blob.

I think it's unlikely that the example you presented would be used very
often. It seems more likely that the array (at least) would use the
@PersistentCollection annotation, at which point we'd treat it as a
ListAttribute.

-mike

On Wed, Jul 6, 2011 at 9:48 AM, Pinaki Poddar <pp...@apache.org> wrote:

> Kevin,
>
>  Always good of you to provide a context for a topic.
>
>  The spec defines 'collection-valued attribute' with lot of words
> essentially meaning anything that implements java.util.Collection (or
> java.util.Map). But the problem with such definition based on syntax (i.e.
> it implements so-and-so interface) versus on semantic (i.e. a collection is
> container of elements) can come to light in the following if we adhere to
> closely:
> @Entity
> public class Bar {}
>
> @Entity
> public class Foo {
>   private Bar[]       a;
>   private List<Bar> b;
> }
>
> would make attribute a and b treated quite differently.
>
> That arrays and list are semantically similar shows up in Java language via
> Arrays.asList() or List.toArray() methods -- List and Array are fungible.
> It
> is JPA, that does not recognize that fact well.
>
> What does Dali do for an attribute like 'a' as in above example?
>
>
>
> -----
> Pinaki
> --
> View this message in context:
> http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6554648.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Pinaki Poddar <pp...@apache.org>.
Kevin,

  Always good of you to provide a context for a topic.

  The spec defines 'collection-valued attribute' with lot of words
essentially meaning anything that implements java.util.Collection (or
java.util.Map). But the problem with such definition based on syntax (i.e.
it implements so-and-so interface) versus on semantic (i.e. a collection is
container of elements) can come to light in the following if we adhere to
closely:
@Entity
public class Bar {}

@Entity
public class Foo {
   private Bar[]       a;
   private List<Bar> b;
}

would make attribute a and b treated quite differently. 

That arrays and list are semantically similar shows up in Java language via
Arrays.asList() or List.toArray() methods -- List and Array are fungible. It
is JPA, that does not recognize that fact well. 

What does Dali do for an attribute like 'a' as in above example?

 

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6554648.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Kevin Sutter <kw...@gmail.com>.
I know I am late to this party, but just to give more concreteness to the
scenario that Mike was describing...

I was working with a customer that hit this exact situation.  The metamodel
code generated by Dali was not processable by our OpenJPA runtime.  When
this customer would generate his metamodel classes with OpenJPA, then
OpenJPA would process just fine.  Without digging into the exact situation
sufficiently, I thought the problem was with Dali and a bug report was
opened against Dali.

https://bugs.eclipse.org/bugs/show_bug.cgi?id=350189

As we dug into the situation a bit further, we discovered the JPA spec
references that Mike outlined previously.  And, thus this conversation...

I just wanted to document that this wasn't just some wild testing or unique
scenario that we dreamed up.  It was a real (WebSphere) customer that hit
this problem and we're trying to figure out the proper source of the error
and get it cleaned up.

Thanks,
Kevin

On Thu, Jun 30, 2011 at 11:37 AM, Michael Dick <mi...@gmail.com>wrote:

> The issue was raised to me via Dali. Based on this discussion I'd say that
> their metamodel generator handles byte[] correctly, suggesting they add a
> feature to use ours seems a bit backwards.
>
> I suspect that fixing it would be more difficult than I'd like. That said,
> we don't persist generic arrays unless they use @PersistentCollection, if
> we
> have FieldMetaData whenever we make a decision, it shouldn't be too bad.
>
> -mike
>
> On Thu, Jun 30, 2011 at 11:14 AM, Pinaki Poddar <pp...@apache.org>
> wrote:
>
> > You also mentioned that the canonical metamodel must match what Dali
> > decided
> > for byte[] as SingularAttibute (which, of course, is a gray area because
> > JPA
> > spec is almost silent about arrays of any component type). In fact, Dali
> > folks, if they have provision for each vendor, allow the vendo to
> generate
> > these metamodel classes rather than generating by themselves o using a
> > specific providers tooling.
> >
> > But given that ali-compliance is also a 'requirement', the source code
> > generation of annotation processor also needs to be tweaked. My hunch is
> > treating arrays differently based on its component type is not going to
> be
> > pretty overall.
> >
> > -----
> > Pinaki
> > --
> > View this message in context:
> >
> http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6533943.html
> > Sent from the OpenJPA Developers mailing list archive at Nabble.com.
> >
>

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Michael Dick <mi...@gmail.com>.
The issue was raised to me via Dali. Based on this discussion I'd say that
their metamodel generator handles byte[] correctly, suggesting they add a
feature to use ours seems a bit backwards.

I suspect that fixing it would be more difficult than I'd like. That said,
we don't persist generic arrays unless they use @PersistentCollection, if we
have FieldMetaData whenever we make a decision, it shouldn't be too bad.

-mike

On Thu, Jun 30, 2011 at 11:14 AM, Pinaki Poddar <pp...@apache.org> wrote:

> You also mentioned that the canonical metamodel must match what Dali
> decided
> for byte[] as SingularAttibute (which, of course, is a gray area because
> JPA
> spec is almost silent about arrays of any component type). In fact, Dali
> folks, if they have provision for each vendor, allow the vendo to generate
> these metamodel classes rather than generating by themselves o using a
> specific providers tooling.
>
> But given that ali-compliance is also a 'requirement', the source code
> generation of annotation processor also needs to be tweaked. My hunch is
> treating arrays differently based on its component type is not going to be
> pretty overall.
>
> -----
> Pinaki
> --
> View this message in context:
> http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6533943.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Pinaki Poddar <pp...@apache.org>.
You also mentioned that the canonical metamodel must match what Dali decided
for byte[] as SingularAttibute (which, of course, is a gray area because JPA
spec is almost silent about arrays of any component type). In fact, Dali
folks, if they have provision for each vendor, allow the vendo to generate
these metamodel classes rather than generating by themselves o using a
specific providers tooling.  

But given that ali-compliance is also a 'requirement', the source code
generation of annotation processor also needs to be tweaked. My hunch is
treating arrays differently based on its component type is not going to be
pretty overall. 

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6533943.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Michael Dick <mi...@gmail.com>.
Craig's summary is what I was trying to get at.

Char and byte arrays are persistable by default. Other types require the
PersistentCollection annotation, and can be handled as collections or
lists.

Some changes to the metamodel generator and to the runtime appear to be
required. I think we're generally in agreement though.

-mike


On Thu, Jun 30, 2011 at 10:29 AM, Pinaki Poddar <pp...@apache.org> wrote:

> Mike,
> Primitive arrays especially for byte and char being treated as a singular
> attribute is something intuitively appealing. If I get the drift of your
> suggested modification, the array of entities would continued to be treated
> as par collection. Is that right?
>
> OpenJPA mostly treats ARRAY and COLLECTION in the same breath. At a first
> glance, it may take some effort to make special provisions based on an
> array's component type.  Or may be there is a short cut at the facade level
> model to make such provision up front. My memory of Metamodel
> implementation
> is fading...
>
> -----
> Pinaki
> --
> View this message in context:
> http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6533762.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Pinaki Poddar <pp...@apache.org>.
Mike,
Primitive arrays especially for byte and char being treated as a singular
attribute is something intuitively appealing. If I get the drift of your
suggested modification, the array of entities would continued to be treated
as par collection. Is that right? 

OpenJPA mostly treats ARRAY and COLLECTION in the same breath. At a first
glance, it may take some effort to make special provisions based on an
array's component type.  Or may be there is a short cut at the facade level
model to make such provision up front. My memory of Metamodel implementation
is fading...

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6533762.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Michael Dick <mi...@gmail.com>.
Let me try to reel this one back in, I think some signal has gotten lost.

The example I'm concerned with is a byte array. The problem I'm trying to
solve is that of compatibility with canonical metamodel classes.

For example, I would expect the canonical metamodel classes generated by
Dali to work with OpenJPA. As I understand it, they do not work because Dali
generates a SingularAttribute for byte arrays.

My read of the spec is that using a SingularAttribute is correct. Collection
valued fields are generally used to refer to relationships. This can be
extended to encompass @PersistentCollections, but shouldn't apply to a byte
array.

While I understand your opinion that the spec came second, I think that the
point of the spec is to address compatibility issues like this one.

-mike

On Wed, Jun 29, 2011 at 1:41 PM, Pinaki Poddar <pp...@apache.org> wrote:

> Arrays are specialized Lists. Or Lists are specialized Arrays. Like
> Rectangle
> is a specialized Square. Or Square is a specialized Rectangle. Formal
> language inheritance concept does not pin this either way but allows one to
> consider either view.
>
> OpenJPA had so far modeled Array as second-class container in a consistent
> manner as it did for java.util.Collection and its subtypes. I support such
> modeling. It also has an extra makeDirty() because of technical complexity
> of tracking changes in second-class containers w.r.t Arrays.
>
> From that viewpoint of maintaining continuity of design principles of the
> original authors, the modeling of Array as List is correct, imo.
>
> Primitive collection requires different treatment. That is why JPA 2.0 had
> to annotate @ElementCollection to distinguish from reference collection.
> Let
> us keep that aside for the time being.
>
> Now on why "X spec says so..." is a weak argument
>
> Specs are combined voices of you and I and all the people who are brave and
> crazy enough to explore new ideas in open source projects. Specs follow
> Open
> Source. Not the other way around. Open Source is the playground where
> technical debate (as we are now engaged in) takes place, where new ideas
> emerge. If the ideas are solid and the democracy of users accept it -- then
> the spec of future years will adopt it.
>
> As far as persistence of Arrays is concerned -- JPA spec says almost
> nothing. The onus is on us as open source developers who have to figure out
> what is a *good* way. If the users accept it -- then we did a good job and
> we can take our view to the experts of spec committee to make that view
> part
> of a standard. Today where JPA spec stands is a testimonial to such effort
> by Hibernate or Kodo and many others who built their software *without* a
> spec guiding them what to do or what is the "right" way. In fact, it is
> they
> who made today's JPA spec possible. That is why I said : "X spec says
> so..."
> is a weak argument in a open source context.
>
>
>
>
>
> -----
> Pinaki
> --
> View this message in context:
> http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6530220.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Pinaki Poddar <pp...@apache.org>.
Arrays are specialized Lists. Or Lists are specialized Arrays. Like Rectangle
is a specialized Square. Or Square is a specialized Rectangle. Formal
language inheritance concept does not pin this either way but allows one to
consider either view. 

OpenJPA had so far modeled Array as second-class container in a consistent
manner as it did for java.util.Collection and its subtypes. I support such
modeling. It also has an extra makeDirty() because of technical complexity
of tracking changes in second-class containers w.r.t Arrays. 

>From that viewpoint of maintaining continuity of design principles of the
original authors, the modeling of Array as List is correct, imo.  

Primitive collection requires different treatment. That is why JPA 2.0 had
to annotate @ElementCollection to distinguish from reference collection. Let
us keep that aside for the time being.

Now on why "X spec says so..." is a weak argument

Specs are combined voices of you and I and all the people who are brave and
crazy enough to explore new ideas in open source projects. Specs follow Open
Source. Not the other way around. Open Source is the playground where
technical debate (as we are now engaged in) takes place, where new ideas
emerge. If the ideas are solid and the democracy of users accept it -- then
the spec of future years will adopt it. 

As far as persistence of Arrays is concerned -- JPA spec says almost
nothing. The onus is on us as open source developers who have to figure out
what is a *good* way. If the users accept it -- then we did a good job and
we can take our view to the experts of spec committee to make that view part
of a standard. Today where JPA spec stands is a testimonial to such effort
by Hibernate or Kodo and many others who built their software *without* a
spec guiding them what to do or what is the "right" way. In fact, it is they
who made today's JPA spec possible. That is why I said : "X spec says so..."
is a weak argument in a open source context.  

   

   

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6530220.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Michael Dick <mi...@gmail.com>.
It's interesting that you think that complying with the spec is a weak
argument.

Say that another vendor, or third party tools have a different
interpretation of the spec. Maybe one of those third party tools generated
your metamodel classes, would be a fair assumption that you'd have to
regenerate the classes to use OpenJPA?

The relevant wording in the spec is:
For every persistent collection-valued attribute z declared by class X,
where the element type
of z is Z, the metamodel class must contain a declaration as follows:
• if the collection type of z is java.util.Collection, then
public static volatile CollectionAttribute<X, Z> z;
• if the collection type of z is java.util.Set, then
public static volatile SetAttribute<X, Z> z;
• if the collection type of z is java.util.List, then
public static volatile ListAttribute<X, Z> z;
• if the collection type of z is java.util.Map, then
public static volatile MapAttribute<X, K, Z> z;
where K is the type of the key of the map in class X

I don't see wording in the spec to suggest that we can consider arrays as
Lists, nor is there wording that says we can't. My first read of the section
above, is that we should treat an array as a singular attribute, but this
isn't my area of expertise either.

To give you a more concrete example, would you consider a byte array a list
of bytes?

Say you have something like this:
@Lob
private byte[] pic;

What would you expect in the metamodel class?
public static volatile ListAttribute<ByteArrayEntity,Byte> pic; // this is
what OpenJPA currently generates
or
public static volatile SingularAttribute<ByteArrayEntity,byte[]> pic; // off
the top of my head - might not be fully baked

-mike


On Wed, Jun 29, 2011 at 10:58 AM, Pinaki Poddar <pp...@apache.org> wrote:

> > At any rate, this seems wrong to me
> what exactly is *this* that seems wrong? That arrays are special lists that
> does not grow? Or something else? Please elaborate -- and please except
> rather weak argument of 'JPA spec says so...'
>
> -----
> Pinaki
> --
> View this message in context:
> http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6529561.html
> Sent from the OpenJPA Developers mailing list archive at Nabble.com.
>

Re: Metamodel generates ListAttribute for arrays instead of SingularAttribute

Posted by Pinaki Poddar <pp...@apache.org>.
> At any rate, this seems wrong to me
what exactly is *this* that seems wrong? That arrays are special lists that
does not grow? Or something else? Please elaborate -- and please except
rather weak argument of 'JPA spec says so...'  

-----
Pinaki 
--
View this message in context: http://openjpa.208410.n2.nabble.com/Metamodel-generates-ListAttribute-for-arrays-instead-of-SingularAttribute-tp6529049p6529561.html
Sent from the OpenJPA Developers mailing list archive at Nabble.com.