|
Home > Archive > Apache JDO Project > December 2005 > Issue 150: Consistency requirements for relationships with mapped-by
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
Issue 150: Consistency requirements for relationships with mapped-by
|
|
| Craig L Russell 2005-12-20, 5:45 pm |
| | |
| Bin Sun 2005-12-21, 2:45 am |
| Wow, that's definitely great!
'Managed Bi-directional Relationship' feature is what
I have been waiting for so long, though this proposal
doesn't fully include MBR, it solved the problem in
most pratical cases.
--- Craig L Russell <Craig.Russell@Sun.COM> wrote:
> Javadogs,
>
> In chapter "15.3 Relationship Mapping" of the spec,
> "changes to the
> field mapped via mapped-by are not reflected in the
> datastore".
>
> However, this conflicts with the text that follows:
>
> "... the column(s) will be changed during commit
> and will therefore
> be visible by both sides in the next transaction.".
>
> I believe that the second part is more important
> than the first part.
> Specifically, if the user makes a change to a
> persistent field, at
> flush or commit time it makes sense to me that the
> implementation
> should make sure that the change is flushed to the
> datastore.
> Further, the spec says that changes will be visible
> by both sides in
> the next transaction, which has implications for
> RetainValues.
>
> I think it's technically feasible for changes to
> either side to be
> reflected in the database, and for RetainValues to
> be handled
> consistently.
>
> <proposed 15.3>
> If two relationships (one on each side of an
> association) are mapped
> to the same column, the field on only one side of
> the association
> needs to be explicitly mapped.
> The field on the other side of the relationship can
> be mapped simply
> by using the mapped-by attribute identifying the
> field on the side
> that defines the mapping. Regardless of which side
> changes the
> relationship, flush (whether done as part of commit
> or explicitly by
> the user) will modify the datastore to reflect the
> change. There is
> no further relationship implied by having both sides
> of the
> relationship map to the same database column(s). In
> particular,
> making a change to one side of the relationship does
> not imply any
> runtime behavior by the JDO implementation to change
> the other side
> of the relationship in memory prior to flush and
> will therefore be
> visible by both sides in the next transaction. If
> the RetainValues
> flag or DetachAllOnCommit is set to true, and the
> relationship field
> is loaded, then the implementation will change the
> field on the other
> side so it is visible after transaction completion.
> Conflicting changes to relationships cause a
> JDOUserException to be
> thrown at flush time. Conflicting changes include:
> adding a related instance with a single-valued
> mapped-by relationship
> field to more than one one-to-many collection
> relationship
> setting both sides of a one-to-one relationship such
> that they do not
> refer to each other
> </proposed 15.3>
>
>
> Craig Russell
> Architect, Sun Java Enterprise System
> http://java.sun.com/products/jdo
> 408 276-5638 mailto:Craig.Russell@sun.com
> P.S. A good JDO? O, Gasp!
>
>
________________________________________
__________
Do You Yahoo!?
Tired of spam? Yahoo! Mail has the best spam protection around
http://mail.yahoo.com
| |
| David Bullock 2005-12-22, 7:45 am |
| Craig L Russell wrote:
> The "in your face" issue I'm wrestling with is the inconsistency in
> the specification where we say that changes are ignored if made to the
> "mapped-by" side and also that changes made to the memory model are
> visible after commit.
> [...]
> It's evident to me that it's possible to detect changes to either side
> of the relationship and make the two sides consistent.
> [...]
> I don't think that it makes sense for JDO that users' model changes to
> be ignored just because they happen to be made to the "wrong side" of
> the relationship.
> [...]
> 3. Inconsistencies should not be accepted, as they indicate user code
> gone bad.
We're mostly in vehement agreement, especially about not ignoring the
user's assignments to fields. I think your proposal is certainly a
clarification and improvement.
It's just that I would include 'stupid user only updated one side of the
relationship' as one of the inconsistencies that causes a
JDOUserException to be thrown at commit. Instead of the JDO runtime
'fixing' the other side as a convenience. I don't want that
convenience. If I've failed to update both sides of a relationship, that
could easily have implications for the correctness of my code before
commit, and I don't want JDO to silently fix things - I want to know.
"Please force me to update both sides", is what I'm saying. I don't
know who is demanding that users be allowed to only update one side of
the relationship. Sure, I'd like that feature IF the update happened
immediately as per managed relationships. But fixing my model after
commit doesn't help me before commit, so you might as well make me do
things manually (which is a coding obligation that I already have when
not using persistence).
So rather than new features I'm asking you to be more stringent!
cheers,
David.
PS. The updated text is more clear, thanks.
| |
| erik@jpox.org 2005-12-22, 7:45 am |
| I agree with the proposal
Quoting Craig L Russell <Craig.Russell@Sun.COM>:
> Hi David,
>
> Thanks for your comments.
>
> The "in your face" issue I'm wrestling with is the inconsistency in
> the specification where we say that changes are ignored if made to
> the "mapped-by" side and also that changes made to the memory model
> are visible after commit. So I took a fresh look at the requirements
> and practical aspects of implementation.
>
> JDO 1.0 requires byte-code enhancement. JDO 2.0 now admits
> implementations that don't use byte-code enhancement, weaving, or
> aspects in order to intercept domain model changes during a
> transaction. Synchronizing the memory model with the database is now
> deferred to flush (which might happen during commit). At flush time,
> the JDO implementation gets control (possibly for the first time
> after loading the instances) and can do whatever the spec requires.
> It's evident to me that it's possible to detect changes to either
> side of the relationship and make the two sides consistent.
>
> The proposal is carefully worded to not require that the
> implementation do extra work in case the memory model is not fully
> instantiated. In particular, it's possible to add a hollow Employee
> to a Department.emps collection without instantiating the Employee
> instance. Similarly, it's possible to set the Employee.dept field to
> a hollow Department without instantiating the Department instance.
>
> The original wording in the JDO 2.0 spec was informed by the work in
> EJB3 which derived from TopLink and Hibernate implementations that
> don't worry much about the "mapped-by" side of the relationship. But
> I don't think that it makes sense for JDO that users' model changes
> to be ignored just because they happen to be made to the "wrong side"
> of the relationship.
>
> This proposal is where I ended up.
>
> 1. JDO implementations get control at flush;
> 2. User changes should not be ignored;
> 3. Inconsistencies should not be accepted, as they indicate user code
> gone bad.
>
> I agree it's a tradeoff. I'd like to see managed relationships in
> memory but given the constraints I don't see it happening for JDO 2.
> And I'd really like to see managed relationships be a separate issue
> addressed in another JSR. It's not just a persistence issue; it's not
> a mapping issue; it's a domain model issue.
>
> Regards,
>
> Craig
>
> Slightly updated for clarity:
>
> <proposed 15.3>
> If two relationships (one on each side of an association) are mapped
> to the same column, the field on only one side of the association
> needs to be explicitly mapped.
> The field on the other side of the relationship can be mapped simply
> by using the mapped-by attribute identifying the field on the side
> that defines the mapping. Regardless of which side changes the
> relationship, flush (whether done as part of commit or explicitly by
> the user) will modify the datastore to reflect the change and will
> update the memory model for consistency. There is no further behavior
> implied by having both sides of the relationship map to the same
> database column(s). In particular, making a change to one side of the
> relationship does not imply any runtime behavior by the JDO
> implementation to change the other side of the relationship in memory
> prior to flush, and there is no requirement to load fields affected
> by the change if they are not already loaded. If the RetainValues
> flag or DetachAllOnCommit is set to true, and the relationship field
> is loaded, then the implementation will change the field on the other
> side so it is visible after transaction completion.
> Conflicting changes to relationships cause a JDOUserException to be
> thrown at flush time. Conflicting changes include:
> adding a related instance with a single-valued mapped-by relationship
> field to more than one one-to-many collection relationship
> setting both sides of a one-to-one relationship such that they do not
> refer to each other
> </proposed 15.3>
>
> On Dec 21, 2005, at 3:52 AM, David Bullock wrote:
>
>
> Craig Russell
> Architect, Sun Java Enterprise System http://java.sun.com/products/jdo
> 408 276-5638 mailto:Craig.Russell@sun.com
> P.S. A good JDO? O, Gasp!
>
>
| |
| Bin Sun 2005-12-23, 7:45 am |
| Hi, David!
I'd like to share some of my ideas. We are
developing heavy stressed web applications based on
JDO. In each bi-di-relation, if the coder has to
assign both sides, the other side(usually a
collection) has to be loaded into memory and cause
much performance penalty. It's more efficient to leave
this synchronization task to the implementation.
This auto-sync behavior doesn't conflicts with the
data model because it's intended by specifying 'mapped
by' in the metadata.
Imagine a simple PC class 'Person', we can easily
do 'person.setIdcard(...)' in a tx, but if we specify
the 'idcard' field as primary-key in the metadata,
this invocation would fail. In this similar case, this
different behavior doesn't conflict with the data
model, because it's intended by specifying
'primary-key' in the metadata too.
You may say JDOUserException is a better choice,
but for the performance issues I mentioned, it's
better to leave sync-task to the implementation, at
least as a javax.jdo.option.
--- David Bullock <db@dawnbreaks.net> wrote:
> Craig L Russell wrote:
>
> inconsistency in
> ignored if made to the
> memory model are
> changes to either side
> consistent.
> users' model changes to
> the "wrong side" of
> indicate user code
>
>
> We're mostly in vehement agreement, especially about
> not ignoring the
> user's assignments to fields. I think your proposal
> is certainly a
> clarification and improvement.
>
> It's just that I would include 'stupid user only
> updated one side of the
> relationship' as one of the inconsistencies that
> causes a
> JDOUserException to be thrown at commit. Instead of
> the JDO runtime
> 'fixing' the other side as a convenience. I don't
> want that
> convenience. If I've failed to update both sides of
> a relationship, that
> could easily have implications for the correctness
> of my code before
> commit, and I don't want JDO to silently fix things
> - I want to know.
>
> "Please force me to update both sides", is what I'm
> saying. I don't
> know who is demanding that users be allowed to only
> update one side of
> the relationship. Sure, I'd like that feature IF
> the update happened
> immediately as per managed relationships. But
> fixing my model after
> commit doesn't help me before commit, so you might
> as well make me do
> things manually (which is a coding obligation that I
> already have when
> not using persistence).
>
> So rather than new features I'm asking you to be
> more stringent!
>
> cheers,
> David.
>
>
> PS. The updated text is more clear, thanks.
>
__________________________________
Yahoo! for Good - Make a difference this year.
http://brand.yahoo.com/cybergivingweek2005/
|
|
|
|
|