[hibernate-issues] [Hibernate-JIRA] Commented: (HBX-1179) <one-to-one> should not generate Sets

Joachim Durchholz (JIRA) noreply at atlassian.com
Mon Mar 14 10:06:08 EDT 2011


    [ http://opensource.atlassian.com/projects/hibernate/browse/HBX-1179?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=40196#action_40196 ] 

Joachim Durchholz commented on HBX-1179:
----------------------------------------

I just found out that the picture changes if the default setting of ON DELETE RESTRICT is changed to ON DELETE CASCADE: Reveng starts generating an additional association, a <many-to-one> with a <unique> tag, just as the hibernate book recommends.
However, the Pojo now contains two associations instead of one, which means Reveng is interpreting stuff in ways I don't understand, so it's not very useful to me. Worse, the new association again generates a Set on the other side of the association.
Unfortunately, I'm not sure whether I'm doing stuff wrong or hitting a Reveng bug, and since the reveng docs don't even mention the relevance of RESTRICT or CASCADE, I don't even know how it's supposed to work.

> <one-to-one> should not generate Sets
> -------------------------------------
>
>                 Key: HBX-1179
>                 URL: http://opensource.atlassian.com/projects/hibernate/browse/HBX-1179
>             Project: Hibernate Tools
>          Issue Type: Bug
>          Components: reverse-engineer
>         Environment: Hibernate Tools version as reported by Eclipse: 3.3.0.v20101016-0359-H111-Beta1
> Feel free to identify the matching release numbers, I can't :-/
>            Reporter: Joachim Durchholz
>
> Hibernate tools does not always recognize one-to-one associations as such, even if specified as <one-to-one> in hibernate.reveng.xml.
> 1. It should generally not silently fall back to one-to-many or many-to-one if it determines that one-to-one is not possible; it should report an error instead. (This allows programmers to correct the database and/or the hibernate.reveng.xml: if it's really a one-to-many, they can move the association to the other table and make it many-to-one; if it should be one-to-one, they can add the missing constraints, giving Hibernate better information about the database schema actually in place.)
> 2. In the following test case, it does not recognize the relationship as one-to-one even though it is, erroneously generating a Set for the <inverse-one-to-one> direction instead of a backlink.
> Workarounds:
> A) Use <inverse-one-to-one exclude="true"/> to prevent Set creation. Works if you don't need the backlink.
> B) Have a backlink field in the target table. Create two one-to-one associations, one for each direction, and use <inverse-one-to-one exclude="true"/>.
> C) Do not reverse engineer the one-to-one association at all and use Criteria, HQL, or SQL to navigate the link.
> D) Subclass DefaultReverseEngineeringStrategy and override isOneToOne() for that particular association.
> Test case:
> Table creation (Oracle 10g)
> CREATE TABLE "HF_DI_BVKRIT" (
>   "BKID" NUMBER(27,0) NOT NULL ENABLE,
>   "VERSION" NUMBER(18,0) DEFAULT 0 NOT NULL ENABLE,
>   "BKNAME" VARCHAR2(40) NOT NULL ENABLE
> ) ;
> ALTER TABLE "HF_DI_BVKRIT" ADD CONSTRAINT "HF_DI_BVKRIT_PK"
>   PRIMARY KEY ("BKID") ENABLE;
> CREATE TABLE "HF_DI_BVKOPF" (
>   "BVID" NUMBER(10,0) NOT NULL ENABLE,
>   "VERSION" NUMBER(18,0) DEFAULT 0 NOT NULL ENABLE,
>   "BVBKID" NUMBER(27,0) NOT NULL ENABLE,
>   "BVGPRS" NUMBER(8,2)
> ) ;
> ALTER TABLE "HF_DI_BVKOPF" ADD CONSTRAINT "HF_DI_BVKOPF_PK"
>   PRIMARY KEY ("BVID") ENABLE;
> ALTER TABLE "HF_DI_BVKOPF" ADD CONSTRAINT "HF_DI_BVKOPF_UK"
>   UNIQUE ("BVBKID") ENABLE;
> ALTER TABLE "HF_DI_BVKOPF" ADD CONSTRAINT "HF_DI_BVKOPF_FK_BVKRIT"
>   FOREIGN KEY ("BVBKID") REFERENCES "HF_DI_BVKRIT" ("BKID") ENABLE;
> Relevant hibernate.reveng.xml section:
>   <table name="HF_DI_BVKOPF">
>     <column name="VERSION" type="long"></column>
>     <foreign-key constraint-name="HF_DI_BVKOPF_FK_BVKRIT">
>       <one-to-one />
>       <inverse-one-to-one />
>     </foreign-key>
>   </table>
> Generated Java classes:
> public class HfDiBvkrit implements java.io.Serializable {
>   private BigInteger bkid;
>   private long version;
>   private String bkname;
>   private Set <HfDiBvkopf> hfDiBvkopfs = new HashSet <HfDiBvkopf> (0);
>   // The above line should have been generated as:
>   // private HfDiBvkopf hfDiBvkopf;
>   ...
> }
> public class HfDiBvkopf implements java.io.Serializable {
>   private BigInteger bvid;
>   private long version;
>   private HfDiBvkrit hfDiBvkrit;
>   private BigDecimal bvgprs;
>   ...
> }
> Reasoning why this should be a one-to-one association (hopefully I didn't make too many errors reversing the roles of left and right table):
> There is a unique key on BVKOPF.BVBKID.
> I.e. a BVKRIT record can find at most one BVKOPF with a BVBKID that matches its BVKRIT.BKID.
> The BVKOPF-BVKRIT association hence must be one-to-*. (1)
> There is a foreign key from BVKOPF.BVBKID to BVKRIT.BKID.
> BKID is a unique key in BVKRIT (it also happens to be the primary key, but that's irrelevant here).
> I.e. a BVKOPF record can find at most one BVKRIT with a BKID that matches its BVKOPF.BVBKID.
> The BVKOPF-BVKRIT association hence must be *-to-one. (2)
> Combining (1) and (2) gives "must be one-to-one", q.e.d.
> See also https://forum.hibernate.org/viewtopic.php?f=6&t=1009989&start=0

-- 
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.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list