Hi there,
after years of not having to deal with databases, I'm back to that
topic.
So I'm still figuring out the best way for myself to do ORM. My first
two attempts were to use JCR (Jackrabbit) and JPA (OpenJPA). JCR
worked
fine although I dropped it because I can easily have >100'000
children
on one node which will result in performance problems or require
work-arounds that I don't particularly like. JPA then just went
against
my views of how databases should be modeled: an intermediate table
for a
simple 1:n relation. Not with me. I couldn't get the whole thing to
work
without the intermediate table. Then I stumbled upon Cayenne (I'm
using
the Trunk) and immediately found myself at home.
Now, my problem: I've been trying to make an abstraction of my data
logic using interfaces, i.e. define an interface for each domain
object
and logic methods grouped in an interface per topic. That works
pretty
well for the JCR and JPA implementations. I wrote the test code
once and
can reuse it for all implementations. With Cayenne, this gets a bit
difficult. I can always implement the domain interfaces in the domain
classes but when it comes to nested collections, this becomes a
problem:
public interface Document extends Serializable {
[..]
Collection<Representation> getRepresentations();
}
public interface Representation extends Serializable {
[..]
}
Generated domain class:
public class DocumentImpl extends _DocumentImpl implements Document {
[..]
}
public abstract class _DocumentImpl extends CayenneDataObject {
[..]
@SuppressWarnings("unchecked")
public List<RepresentationImpl> getRepresentations() {
return
(List<RepresentationImpl>)readProperty("representations");
}
}
List<RepresentationImpl> is not compatible with the
List<Representation>
in the interface.
So, I'm wondering if there's a better way to do this that avoids this
problem, preferably without removing generics.
I was thinking that adding the interface in the object model could
optionally be specified and the code generator could, for example,
do an
"implements Document" for _DocumentImpl and return
List<Representation>.
Of course, that would require some casting to DataObject in
addToManyTarget() for example. That's probably undesired and would
probably
require quite a bit of work. But maybe there's a better way. I could
probably proxy/adapt the whole stuff but that's probably bad
performance- and effort-wise. Maybe I simply have to give up my
puristic
data access abstraction. But I wanted to ask around first.
---
While I'm at it: Can I ask why DeleteQuery has been deprecated? I'd
rather use that instead of EJBQLQuery. Not having to concatenate
strings
to build queries is one of the features that makes Cayenne appeal
to me
so much. I've had stuff like that back in my Delphi times and I liked
that very much.
Thanks a lot for any ideas and thoughts,
Jeremias Maerki