Fornax-Platform
Forum

[Sculptor] uni-directional one-to-many mapping?

View: New views
10 Messages — Rating Filter:   Alert me  

[Sculptor] uni-directional one-to-many mapping?

by polly.c.chang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi,

Is it possible to map a uni-directional one-to-many mapping?  From looking at the documentation and template code, it looks like one has to mark the Reference as "inverse", which is a bi-directional mapping.  I just want to have a simple uni-directional mapping.

Thanks!
--Polly


Re: [Sculptor] uni-directional one-to-many mapping?

by Patrik Nordwall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Do you need something like this, i.e. Moon doesn't refer back to Planet?

Entity Planet {
   - @Set<Moon> moons
}

Entity Moon {
}


This will result in a uni-directional many association, but will be implemented in the database as many-to-many.

To implement it with an ordinary foreign key in the child table you have to add inverse

Entity Planet {
   - @Set<Moon> moons inverse
}

Doc: http://www.fornax-platform.org/cp/display/fornax/3.+Advanced+Tutorial+(CSC)#3.AdvancedTutorial(CSC)-AdditionalReferenceFeatures

/Patrik

polly.c.chang wrote:
Hi,

Is it possible to map a uni-directional one-to-many mapping?  From looking at the documentation and template code, it looks like one has to mark the Reference as "inverse", which is a bi-directional mapping.  I just want to have a simple uni-directional mapping.

Thanks!
--Polly

Re: [Sculptor] uni-directional one-to-many mapping?

by polly.c.chang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Patrik,

Yup, that's what we tried.  We ran into a problem though.  Here's the definition:

                Entity PropertyData {
                   - List<@PropertyItem> items fetch="join" cascade="all" inverse
                }
               
                ValueObject PropertyItem {
                        String stuff nullable
                }

When we did that, it created the correct one-to-many Hibernate mapping like this:

<hibernate-mapping default-cascade="none" default-access="property" default-lazy="true" auto-import="true">
        <class name="com.foo.PropertyData" table="OM_PROPERTY_DATA" mutable="true" polymorphism="implicit" dynamic-update="false" dynamic-insert="false" select-before-update="false" optimistic-lock="version">
                ...
                <list name="items" inverse="true" cascade="all" fetch="join" lazy="false" mutable="true" optimistic-lock="true" embed-xml="true">
                        <key column="C_PROPERTY_DATA" on-delete="noaction"/>
                        <index column="C_ITEM_INDEX"/>
                        <one-to-many class="com.foo.PropertyItem" not-found="exception" embed-xml="true"/>
                </list>
        </class>
</hibernate-mapping>


Then when we saved a PropertyData with PropertyItems, Hibernate created all the PropertyData and PropertyItem records, but the C_PROPERTY_DATA foreign key column in PropertyItem was null.  So when we retrieve the PropertyData again, it does not have any PropertyItems attached to it.  Isn't "inverse" in Hibernate only used for bi-directional relationships?  How does the C_PROPERTY_DATA key get set?

Please let me know if I broke something or if we are doing something wrong.

Thanks!
--Polly

Patrik Nordwall wrote:
Do you need something like this, i.e. Moon doesn't refer back to Planet?

Entity Planet {
   - @Set<Moon> moons
}

Entity Moon {
}


This will result in a uni-directional many association, but will be implemented in the database as many-to-many.

To implement it with an ordinary foreign key in the child table you have to add inverse

Entity Planet {
   - @Set<Moon> moons inverse
}

Doc: http://www.fornax-platform.org/cp/display/fornax/3.+Advanced+Tutorial+(CSC)#3.AdvancedTutorial(CSC)-AdditionalReferenceFeatures

/Patrik

Re: [Sculptor] uni-directional one-to-many mapping?

by Patrik Nordwall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Aha, it might be a bug, does it work if you remove the inverse from the hbm file?
/P

Re: [Sculptor] uni-directional one-to-many mapping?

by polly.c.chang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Patrik,

Yes, we found that if we remove the "inverse" from the hbm file, and the "key" does not say on-delete="cascade", then it works.

Thanks,
Polly




Patrik Nordwall wrote:
Aha, it might be a bug, does it work if you remove the inverse from the hbm file?
/P

Re: [Sculptor] uni-directional one-to-many mapping?

by Patrik Nordwall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Please, add a jira bug report and we will fix it. Maybe you can solve it and supply a patch.
/Patrik

Re: [Sculptor] uni-directional one-to-many mapping?

by polly.c.chang :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Patrik,

I have another question for you--
In the hbm file, to get the "key" to not say "on-delete="cascade"", we need to set this property right?

db.mysql.onDeleteCascade=false

Is this the right thing to do or is that for something else?

Also, do you have a regression test suite that tests all these different kinds of reference mappings?  I see that you have different kinds of mappings in the "library" project, but they don't seem to be broken out into tests like "one-to-many unidirectional", "one-to-many bidirectional", etc., so I am not sure what kind of coverage there is.  I just want to make sure that I don't break other mappings, because obviously there are other cases where if the design file says "inverse", we do want to output "inverse=true".

I created the JIRA here:
http://www.fornax-platform.org/tracker/browse/CSC-279

Thanks,
Polly

Patrik Nordwall wrote:
Please, add a jira bug report and we will fix it. Maybe you can solve it and supply a patch.
/Patrik

Re: [Sculptor] uni-directional one-to-many mapping?

by deepshar027 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hey Patrick,

I am facing this problem.

Consider this..similar like your example.

Entity Inventory{
  - List<@Item> items
}
Entity Item{
}

This generates an additional table INVENTORY_ITEM which I dont want (many-2-many relationship.)
I want to have unidiretional relationship(one-2-many) as only inventory can have items.

Now If I do the following

CASE:1

Entity Inventory{
  - List<@Item> items inverse
}

I see a reference of INVENTORY in item table which is not expected.
CREATE TABLE ITEM (
  ITEM_ID NUMBER(20) NOT NULL,
  INVENTORY NUMBER(20)  ,
);

What I want to have is just below and there should no reference of Inventory in Item table.

CREATE TABLE INVENTORY (
     INVENTORY_ID NUMBER(20) NOT NULL,
     ITEM_ID NUMBER(20) NOT NULL,
)

CASE 2:

I did the following(Not sure why but I read somewhere that inverse creates a reference in the child table)
As such the following doesnt look correct to me but still I tried

Entity Inventory{
 }
Entity Item{
    - List<@Inventory> inv inverse
}

It does this which seems okk...although it creates this INV_INDEX(INTEGER) which I'll have to fix somehow to make NUMBER

CREATE TABLE INVENTORY (
  INVENTORY_ID NUMBER(20) NOT NULL,
  INV_INDEX INTEGER(10),
  ITEM NUMBER(20)            
);

This is fine so far....but in Item.hbm.xml I see
<list name="inv">
      <key column="ITEM"/>  
      <index column="INV_INDEX"/>  
      <one-to-many class="com.bookonz.inventory.domain.Inventory"/>
    </list>  

I am not sure if this is correct? Should Item.hbm hold a reference to Inventory?


Please provide your inputs on this.

Thanks,
Deepak.


Do you need something like this, i.e. Moon doesn't refer back to Planet?

Entity Planet {
   - @Set<Moon> moons
}

Entity Moon {
}


This will result in a uni-directional many association, but will be implemented in the database as many-to-many.

To implement it with an ordinary foreign key in the child table you have to add inverse

Entity Planet {
   - @Set<Moon> moons inverse
}

Doc: http://www.fornax-platform.org/cp/display/fornax/3.+Advanced+Tutorial+(CSC)#3.AdvancedTutorial(CSC)-AdditionalReferenceFeatures

/Patrik

polly.c.chang wrote:
Hi,

Is it possible to map a uni-directional one-to-many mapping?  From looking at the documentation and template code, it looks like one has to mark the Reference as "inverse", which is a bi-directional mapping.  I just want to have a simple uni-directional mapping.

Thanks!
--Polly


Re: [Sculptor] uni-directional one-to-many mapping?

by Patrik Nordwall :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Hi Deepak,

CASE2 is wrong way.

You have two options.
1) many-to-many join table. This is the default.
2) foreign key column in ITEM. This is the result of inverse keyword.

Alternative 2 is more efficient, but it introduces a dependency at the db level from item to inventory, which is sometimes unwanted, especially when inventory and item are in different modules.

I don't think you can design this in the database in any other way.

Below INVENTORY table will not be able reference several items for one inventory.
CREATE TABLE INVENTORY (
     INVENTORY_ID NUMBER(20) NOT NULL,
     ITEM_ID NUMBER(20) NOT NULL,
)


/Patrik




deepshar027 wrote:
Hey Patrick,

I am facing this problem.

Consider this..similar like your example.

Entity Inventory{
  - List<@Item> items
}
Entity Item{
}

This generates an additional table INVENTORY_ITEM which I dont want (many-2-many relationship.)
I want to have unidiretional relationship(one-2-many) as only inventory can have items.

Now If I do the following

CASE:1

Entity Inventory{
  - List<@Item> items inverse
}

I see a reference of INVENTORY in item table which is not expected.
CREATE TABLE ITEM (
  ITEM_ID NUMBER(20) NOT NULL,
  INVENTORY NUMBER(20)  ,
);

What I want to have is just below and there should no reference of Inventory in Item table.

CREATE TABLE INVENTORY (
     INVENTORY_ID NUMBER(20) NOT NULL,
     ITEM_ID NUMBER(20) NOT NULL,
)

CASE 2:

I did the following(Not sure why but I read somewhere that inverse creates a reference in the child table)
As such the following doesnt look correct to me but still I tried

Entity Inventory{
 }
Entity Item{
    - List<@Inventory> inv inverse
}

It does this which seems okk...although it creates this INV_INDEX(INTEGER) which I'll have to fix somehow to make NUMBER

CREATE TABLE INVENTORY (
  INVENTORY_ID NUMBER(20) NOT NULL,
  INV_INDEX INTEGER(10),
  ITEM NUMBER(20)            
);

This is fine so far....but in Item.hbm.xml I see
<list name="inv">
      <key column="ITEM"/>  
      <index column="INV_INDEX"/>  
      <one-to-many class="com.bookonz.inventory.domain.Inventory"/>
    </list>  

I am not sure if this is correct? Should Item.hbm hold a reference to Inventory?


Please provide your inputs on this.

Thanks,
Deepak.

Re: [Sculptor] uni-directional one-to-many mapping?

by deepshar027 :: Rate this Message:

Reply to Author | View Threaded | Show Only this Message

Patrick,
Thanks for the quick response especially on a holiday.!

I understood what you mean.I think I'll live with the 1st option you gave.

Deepak.


Hi Deepak,

CASE2 is wrong way.

You have two options.
1) many-to-many join table. This is the default.
2) foreign key column in ITEM. This is the result of inverse keyword.

Alternative 2 is more efficient, but it introduces a dependency at the db level from item to inventory, which is sometimes unwanted, especially when inventory and item are in different modules.

I don't think you can design this in the database in any other way.

Below INVENTORY table will not be able reference several items for one inventory.
CREATE TABLE INVENTORY (
     INVENTORY_ID NUMBER(20) NOT NULL,
     ITEM_ID NUMBER(20) NOT NULL,
)


/Patrik




deepshar027 wrote:
Hey Patrick,

I am facing this problem.

Consider this..similar like your example.

Entity Inventory{
  - List<@Item> items
}
Entity Item{
}

This generates an additional table INVENTORY_ITEM which I dont want (many-2-many relationship.)
I want to have unidiretional relationship(one-2-many) as only inventory can have items.

Now If I do the following

CASE:1

Entity Inventory{
  - List<@Item> items inverse
}

I see a reference of INVENTORY in item table which is not expected.
CREATE TABLE ITEM (
  ITEM_ID NUMBER(20) NOT NULL,
  INVENTORY NUMBER(20)  ,
);

What I want to have is just below and there should no reference of Inventory in Item table.

CREATE TABLE INVENTORY (
     INVENTORY_ID NUMBER(20) NOT NULL,
     ITEM_ID NUMBER(20) NOT NULL,
)

CASE 2:

I did the following(Not sure why but I read somewhere that inverse creates a reference in the child table)
As such the following doesnt look correct to me but still I tried

Entity Inventory{
 }
Entity Item{
    - List<@Inventory> inv inverse
}

It does this which seems okk...although it creates this INV_INDEX(INTEGER) which I'll have to fix somehow to make NUMBER

CREATE TABLE INVENTORY (
  INVENTORY_ID NUMBER(20) NOT NULL,
  INV_INDEX INTEGER(10),
  ITEM NUMBER(20)            
);

This is fine so far....but in Item.hbm.xml I see
<list name="inv">
      <key column="ITEM"/>  
      <index column="INV_INDEX"/>  
      <one-to-many class="com.bookonz.inventory.domain.Inventory"/>
    </list>  

I am not sure if this is correct? Should Item.hbm hold a reference to Inventory?


Please provide your inputs on this.

Thanks,
Deepak.