From: Arved Sandstrom on
kamiseq wrote:
>>>>>> Puzzle 1: Why are you explicitly allocating an ArrayList to
>>>>>> 'objectsCfgSet'?
>> kamiseq wrote:
>>>>> why not? and plus you dont need to check every time if collection is
>>>>> null or not. this is not a problem here
>> It's not that I think that initialization was wrong, necessarily. As I
>> stated, it's atypical. Not one bit of training literature that I've read has
>> done that, and not one bit of the JPA code I've worked with has, either.
>
> cos it doesnt hurt :) in my application I am focused on collection
> itself. All I care about id if collection has 0 or more items. so if
> didn't initialize with ArrayList then there would be a situation when
> collection is null as JPA will not insert empty collection. from JPA
> and application point of view null reference is exactly the same as
> empty collection. but if collection is already there I don't need to
> check in my code for nulls. if you want to select, add or remove item
> or list items you need to be sure that collection is initialized. I
> still doesnt understand where this can be a problem and this is common
> pattern I and my friends apply
>

It's not a problem per se, it's just uncommon. The reason it's uncommon
is because in normal operation one would expect that in the database the
relationship would (or could) be populated. That is, there would
actually be rows in a child table that have the foreign key of the
parent. In which case initializing with that empty ArrayList is useless
to you; you cannot use it.

To put it another way, you're coding up the JPA entity class in the
expectation that relationships will be empty. This is fine for creating
new parent POJOs, creating new children POJOs, adding the children to
the existing collections, and persisting the parents (assuming
cascades), but when it comes time to read/find existing parent entities,
those initialized empty ArrayLists will simply be discarded. I the
latter case you cannot assume that there are no children.

The lifecycle of typical JPA entities in enterprise apps that I have
worked on is pretty intuitive - they only get created once. :-) But they
get accessed dozens or hundreds of times, and each time a child in a
certain relationship may be added or removed. In this picture
initializing the relationships to empty lists is unusual.

AHS
From: Tom Anderson on
On Wed, 30 Dec 2009, Lew wrote:

> Tom Anderson wrote:
> Lew wrote:
>>>>> Puzzle 1: Why are you explicitly allocating an ArrayList to
>>>>> 'objectsCfgSet'?
>
> kamiseq wrote:
>>>> why not? and plus you dont need to check every time if collection is null
>>>> or not. this is not a problem here
>
> Lew wrote:
>>> Why not? Because it's atypical of JPA code and I haven't seen that done.
>>> Usually you either let the JPA engine fill it
>
> Tom Anderson wrote:
>> Which won't happen before the JPA provider has got its hands on it, so:
>>
>> new GenObject().objectsCfgSet.add(something);
>>
>> Will fail, right?
>
> Well, duhh. You're supposed to pass in the List, not depend on it being
> there. That's why there's a setter for it.

'Duhh'? 'Supposed'? I don't know about you, Lew, but i quite like having
constructors that create objects that are in a usable state, not ones
which i then have to run round initialising before i can use them.

> And it will certainly fail if 'objectsCfgSet' were properly declared as
> 'private'.

Of course. But you and i both understand that that's not the point we're
discussing.

>> They're using setters because they're using property access - note the @Id
>> annotation on the getCustomerID() method rather than the id field. That
>> means they have to use setters to set fields. Kamiseq is using field
>> access, which means he can access the fields directly. There's no
>> JPA-specific reason for him to use a setter rather than direct access.
>
> There is a common idiom, universal to all the training literature on JPA, to
> have setters for even the collections.

It's an idiom that's common throughout all java development, in fact. That
doesn't mean it's a good one.

> Furthermore, when you set up field-level annotations you still have bean
> patterns for the properties, and the variables remain 'private'. Your
> point does not apply.

What? My point is that you're using property access, you *must* use
setters to set fields, and that if you're using field access, you *can*
use direct assignments. Apologies if i didn't make my point clearly, but
it *does* apply.

> It's not that I think that initialization was wrong, necessarily. As I
> stated, it's atypical. Not one bit of training literature that I've
> read has done that, and not one bit of the JPA code I've worked with
> has, either. So it looked odd, and I wondered why he did it. A
> perfectly reasonable question, when you encounter an idiom that none of
> the experts use.

That looks dangerously like an argument from authority to me, which as you
well know is a logical fallacy. Anyway, if the code you've seen has
setters for all its persistent properties, then i submit that it wasn't
written by experts - setters should be used when there's a good
domain-driven reason for them, and not otherwise, which will very rarely
indeed mean that all properties have setters.

Still, since everyone likes a black swan, here's another post from my
favourite Dutch JPA pundit, showing that at least one expert prefers field
access and sparing use of getters and setters:

http://blog.xebia.com/2009/06/13/jpa-implementation-patterns-field-access-vs-property-access/

And an older and more general one about getters and setters:

http://www.javaworld.com/javaworld/jw-09-2003/jw-0905-toolbox.html

> Now I'm wondering why the OP took the question as an attack instead of a
> request for information.

That, alas, i cannot help you with.

> Anyway, once you persist the object, the initially-allocated List goes
> away and you lose control of whether it's null. So the point of not
> having to check if the collection is null doesn't apply, either.

Is that so? Will persisting an object ever cause a list field to be set to
null? If a list is nonexistent in the database (because there are no rows
in the join table, or no rows in the target table with a matching foreign
key), won't the JPA provider map that to an empty list in the JVM? This is
an honest question - i don't know JPA well at all.

> I think it's best to stick with the way JPA was designed, and I infer
> from the universal absence of collection initialization in the training
> literature that it was designed not to need it.

I've already given you an example where it is needed.

> I've seen what can happen to ORM code when it deviates from the intended
> idioms. You introduce epicycles that get ever more rococo.

I am certainly with you in opposing epicyclicity and rocociousness. If
explicitly initialising a list led to difficulty with JPA, then i would
reconsider doing that. But only then.

> Entity objects are not really meant for a lot of manipulation outside
> the JPA context or by application logic.

No, no, no. JPA is a mechanism, not a policy - JPA entities are not
'meant' for anything. You might think it's a good idea to use JPA entities
that way, but it's something i'd disagree very strongly with you over -
what you're advocating is an Anemic Domain Model, and it's a bad thing
(Martin Fowler says so, so it must be true! :) ):

http://martinfowler.com/bliki/AnemicDomainModel.html

tom

--
Please! Undo clips before opening handle.
From: Arved Sandstrom on
Tom Anderson wrote:
> On Wed, 30 Dec 2009, Lew wrote:
>
[ SNIP ]

>> Entity objects are not really meant for a lot of manipulation outside
>> the JPA context or by application logic.
>
> No, no, no. JPA is a mechanism, not a policy - JPA entities are not
> 'meant' for anything. You might think it's a good idea to use JPA
> entities that way, but it's something i'd disagree very strongly with
> you over - what you're advocating is an Anemic Domain Model, and it's a
> bad thing (Martin Fowler says so, so it must be true! :) ):
>
> http://martinfowler.com/bliki/AnemicDomainModel.html
>
> tom

I'm in general agreement with what's said in that link. However, in the
context of JPA, I myself don't think of the entity classes by themselves
as defining the domain layer in its entirety. I don't think of JPA
entity classes as being domain classes at all, not by definition. Some
happen to correspond to domain classes, some don't. To me JPA entity
classes are fine-grained Java mappings to RDBMS tables, and that's about
it. They are at the same level as iBatis mapping files.

I tend to think of DAOs, which map to the real domain classes, as being
the domain layer. Some JPA entities happen to have a 1:1 mapping to a
domain class - many do not, and really aren't more than value objects or
DTOs.

AHS
From: Tom Anderson on
On Sat, 2 Jan 2010, Arved Sandstrom wrote:

> Tom Anderson wrote:
>> On Wed, 30 Dec 2009, Lew wrote:
>>
>>> Entity objects are not really meant for a lot of manipulation outside the
>>> JPA context or by application logic.
>>
>> No, no, no. JPA is a mechanism, not a policy - JPA entities are not 'meant'
>> for anything. You might think it's a good idea to use JPA entities that
>> way, but it's something i'd disagree very strongly with you over - what
>> you're advocating is an Anemic Domain Model, and it's a bad thing (Martin
>> Fowler says so, so it must be true! :) ):
>>
>> http://martinfowler.com/bliki/AnemicDomainModel.html
>
> I'm in general agreement with what's said in that link. However, in the
> context of JPA, I myself don't think of the entity classes by themselves
> as defining the domain layer in its entirety. I don't think of JPA
> entity classes as being domain classes at all, not by definition. Some
> happen to correspond to domain classes, some don't. To me JPA entity
> classes are fine-grained Java mappings to RDBMS tables, and that's about
> it. They are at the same level as iBatis mapping files.
>
> I tend to think of DAOs, which map to the real domain classes, as being
> the domain layer. Some JPA entities happen to have a 1:1 mapping to a
> domain class - many do not, and really aren't more than value objects or
> DTOs.

Interesting. Are you essentially using JPA entities as behind-the scenes
data holders, wrapped by real domain objects? Or are you saying your
domain objects are more like a service layer? Could i trouble you for a
very small example of this, just in outline?

tom

--
The real romance is out ahead and yet to come. The computer revolution
hasn't started yet. -- Alan Kay
From: Arved Sandstrom on
Tom Anderson wrote:
> On Sat, 2 Jan 2010, Arved Sandstrom wrote:
>
>> Tom Anderson wrote:
>>> On Wed, 30 Dec 2009, Lew wrote:
>>>
>>>> Entity objects are not really meant for a lot of manipulation
>>>> outside the JPA context or by application logic.
>>>
>>> No, no, no. JPA is a mechanism, not a policy - JPA entities are not
>>> 'meant' for anything. You might think it's a good idea to use JPA
>>> entities that way, but it's something i'd disagree very strongly with
>>> you over - what you're advocating is an Anemic Domain Model, and it's
>>> a bad thing (Martin Fowler says so, so it must be true! :) ):
>>>
>>> http://martinfowler.com/bliki/AnemicDomainModel.html
>>
>> I'm in general agreement with what's said in that link. However, in
>> the context of JPA, I myself don't think of the entity classes by
>> themselves as defining the domain layer in its entirety. I don't think
>> of JPA entity classes as being domain classes at all, not by
>> definition. Some happen to correspond to domain classes, some don't.
>> To me JPA entity classes are fine-grained Java mappings to RDBMS
>> tables, and that's about it. They are at the same level as iBatis
>> mapping files.
>>
>> I tend to think of DAOs, which map to the real domain classes, as
>> being the domain layer. Some JPA entities happen to have a 1:1 mapping
>> to a domain class - many do not, and really aren't more than value
>> objects or DTOs.
>
> Interesting. Are you essentially using JPA entities as behind-the scenes
> data holders, wrapped by real domain objects? Or are you saying your
> domain objects are more like a service layer? Could i trouble you for a
> very small example of this, just in outline?
>
> tom
>
Assuming your email is good, I can sanitize some work stuff and send
some examples that way. We just recently went through this exercise on a
client site, where several apps had JPA but no data access layer (i.e.
persistence code was scattered everywhere, including in the web tier),
and in the course of building a DAL we realized that the DAOs most
useful to the service layer (or to other DAOs in the domain layer)
really did not, in most cases, map 1:1 to JPA entities.

Yes, in a nutshell, in this picture JPA entities are both
behind-the-scenes and low-level. Basically data holders as you say.

As one very simple example, if you have two JPA entities related by a
OneToMany/ManyToOne, and that's logically a strong composition
relationship, it's probably more useful to have a single DAO that
handles both entities. Logically the real domain object is the parent +
those entities that can only co-exist with the parent. JPA does provide
some facilities like @Embedded and @Embeddable to handle some of this
for 1:1 situations), but I personally prefer to dispense with
annotations like these, and to have explicit domain logic manage
composition or aggregation relationships.

As an aside, I'm not entirely happy with that Fowler link (nor with Eric
Evans :-)). If I read it correctly they are suggesting that business
rules live only in the domain layer (this is using their definitions of
domain and service layers). I don't buy that - I think there are 2 types
of business rules, and one set lives in the service layer.

AHS