OneToOne not optional dependent entity wrong persist order
----------------------------------------------------------
Key: HHH-6403
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-6403
Project: Hibernate Core
Issue Type: Bug
Components: core
Affects Versions: 3.6.5
Environment: Tested with hibernate-core 3.6.3.Final and 3.6.5.Final, database
MySQL 5.1 with InnoDB (for foreign key costraints)
Reporter: Diego Salvi
Attachments: hib_1to1_dependent_optional_false.tar.gz
There's a problem with dependent entity persist order in a one to one relationship.
Given 2 entity ParentEntity and DependentEntity in a relationship one to one and with the
second one completely dependent from first (DependentEntity PK is ParentEntity PK) I
can't set optional=false one ParentEntity relationship side.
If optional=false is set on ParentEntity side DepententEntity will be persisted first but
it can't because his PK is a FK to ParentEntity and it results in a constraint
violation.
I've tried to check why this happen and I think that the problem resides in a wrong
assumption in:
{code:title=OneToOneSecondPass.doSecondPass(Map persistentClasses)[lines
105:110]|borderStyle=solid}
if ( !optional ) value.setConstrained( true );
value.setForeignKeyType(
value.isConstrained() ?
ForeignKeyDirection.FOREIGN_KEY_FROM_PARENT :
ForeignKeyDirection.FOREIGN_KEY_TO_PARENT
);
{code}
This assumes that if relation isn't optional then foreign key goes from parent to
child (ie.: parent has a field that point to a child field) that is at least a
over-simplification. From this wrong direction come a wrong persisting order.
Please be aware that a OneToOne bidirectional non optional relationship is't a silly
and insane mapping and can be useful in many environment. It could be mapped as
opional=true but then we have fetch problem because FetchType.LAZY can't be
fulfilled.
I've added a simple test case with 2 entity. It uses annotations and entity-manager
(but the real problem is on core).
Just change persistence.xml to match your db user and password and set to an empty schema
(it is already set as create-drop). Failing test is: hib.test.PersistTest.persist()
I'm listing most important entity mappings for quick reference (in attached test case
are obviously complete), as you can see the are really simple (I've tried to use
default as much as I could):
{code:title=ParentEntity|borderStyle=solid}
[...]
@OneToOne( optional = false, cascade = CascadeType.PERSIST, mappedBy =
"parentEntity" )
public DependentEntity getDependentEntity()
{
return dependentEntity;
}
[...]
{code}
{code:title=ParentEntity|borderStyle=solid}
[...]
@Id
@GeneratedValue( generator="foreign" )
@GenericGenerator( name="foreign", strategy = "foreign",
parameters = @Parameter( name="property",
value="parentEntity" ) )
public Integer getId()
{
return id;
}
[...]
@OneToOne( optional = false )
@PrimaryKeyJoinColumn
public ParentEntity getParentEntity()
{
return parentEntity;
}
[...]
{code}
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira