You have found a bug for sure, so JIRA can be used :-)
Thanks for having tracking down the bug, that will help a lot.
When you use an embeddedaccessor, you expect the information to be
filled through alternative properties, hence a noop here.
3. was my initial thought, why do you think it won't help for multi
column mapping?
[EMAIL PROTECTED] wrote:
Hi Emmanuel,
I think we might have found a bug in
BindHelper.bindPropertiesByColumns, want to run by you to see if it's
worth while submitting to Jira.
What we are trying to do is to associate two attributes of the same
type to an object.
i.e.,
class Deal {
@ManyToOne
@JoinColumn(name = "a_customer_id", referencedColumnName =
"customer_id", nullable = true)
Customer a;
@ManyToOne
@JoinColumn(name = "b_customer_id", referencedColumnName =
"customer_id", nullable = true)
Customer b;
}
// note: customer id is not a pk
class Customer {
@Column(name = "customer_id")
String customerId;
}
When loading deal object, customer a is always populated correctly but
customer b will only be populated occasionally (depending on your luck!).
After digging through Hibernate annotation source, I think I've found
the cause of the problem in BindHelper.bindPropertiesByColumns where
HashSet is being used.
From looking through the source, my understanding is that hibernate
will create a synthetic property for each of the customer Deal.a and
Deal.b and add it to a list of properties type mapping within Customer
persistent class object. This type mapping is then used to hydrate
Deal.a and Deal.b when Deal object is being resolved.
When synthetic property for Deal.a is being created, the
propertymapping is straight forward because only customerId property
is available in the Customer persistent class. Deal.a is then mapped
simply to a simple type of Customer.customerId.
Subsequently, when synthetic property for Deal.b is being created
(BindHelper:97), the property mapping has two possible values - one is
the Customer.customerId, the other is the recently created synthetic
mapping (_Deal_a). These two values are extracted out and put into a
HashSet (BindHelper.bindPropertiesByColumn:190). The hashset is then
the being iterated through to return the first value of iterator
(which the order is not guaranteed). Obviously it would be wrong to
create a synthetic property for Deal.b with synthetic property _Deal_a
type mapping (which is what occasionally happens).
Upon load, hibernate core will then attempt to hydrate Deal.a by
instantiating Customer (_Deal_a) type object and inject a_customer_id
into an instance of _Deal_a type. This will result in a correct load.
When hibernate core attempt to hydrate Deal.b, it will instantiate
Customer (_Deal_b) type object. However, _Deal_b type object mapps to
an embedded _Deal_a type. So it will then recurse through the embedded
type, instantiate Customer (_Deal_a) type object, assign b_customer_id
into embedded Customer.customerId after which instance of
Customer(_Deal_a) will be assigned to Customer.customerId (_Deal_b).
This assignment is done via
EmbeddedPropertyAccessor.EmbeddedSetter.set method - which looks like
a null implementation. The result is that Deal.b won't be set and no
errors is being reported at all. What worst is that the system can
appear to have been working most of the time, but if you add
additional attribute to class Deal to disturb the balance of the
hashcode generation, then all of the sudden it won't work.
I can think of a couple of fixes in BindHelper.bindPropertiesByColumns:
1. Instead of using HashSet we use an ordered set to guarantee the
order, this way the native properties will always be returned first.
2. Use List instead of Set to guarantee the order - the values being
added in to the columnsToProperty map can never be null or repeated
anyway.
3. Filter out all of the synthetic properties from columnsToProperty
mapping (this propbably wouldn't help for muti column mapping?).
BTW: It also perplex me why
EmbeddedPropertyAccessor.EmbeddedSetter.set method would do nothing
and report no error when it can't set the property.
Sorry for the lengthy email but it's a fairly subtle bug that can't
always be replicated so I thought it's worth while explaining in
details. Let me know if you want me to submit this to Jira. We have
opted for option 2 on local fix and it appear to be working well.
Regards,
rOnn c.
##########################################################
DISCLAIMER:
This email and any attachment may contain confidential information.
If you are not the intended recipient you are not authorized to copy
or disclose all or any part of it without the prior written consent
of Toyota.
Opinions expressed in this email and any attachments are those of the
sender and not necessarily the opinions of Toyota.
Please scan this email and any attachment(s) for viruses.
Toyota does not accept any responsibility for problems caused by
viruses, whether it is Toyota's fault or not.
##########################################################
-------------------------------------------------------
This SF.Net email is sponsored by xPML, a groundbreaking scripting language
that extends applications into web and mobile media. Attend the live webcast
and join the prime developer group breaking into this new coding territory!
http://sel.as-us.falkag.net/sel?cmd=lnk&kid=110944&bid=241720&dat=121642
_______________________________________________
hibernate-devel mailing list
hibernate-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/hibernate-devel