问题
How do I join two tables as many-to-one and one-to-many in nHibernate. They both have the same 'PLAN_ID' as the key column. My Database structures pre-existing.
Below is the mapping I am using and the error I'm getting:
Table: PLANN (one)
PLAN_ID <-- PRIMARY KEY
START_DATE
CHECK_CHAR
...
Table: PLANN_DOCUMENT (to many)
PLAN_ID <-- PRIMARY KEY
DOC_ID <-- ID to a DOCUMENT table
DOC_NAME
DOC_TYPE
Plann class:
public virtual... PlanId, StartDate, CheckChar, PlanStatus,
public virtual ISet<DocsysHoldingDoc> DocsysHoldingDocs { get; set; }
public virtual DocsysHoldingDoc DocsysHoldingDoc { get; set; }
PlannDocument Class:
public virtual...PlanId, DocId, DocName, DocType
public virtual Plann PlannItem { get; set; }
Plann HBM XML
<class name="Plann" abstract="true" table="PLANN">
<id name="PlanId" column="PLAN_ID"
<generator class="assigned"/>
</id>
<property name="StartDate" column="START_DATE" />
<property name="CHECK_CHAR" column="CHECK_CHAR" />
...
<set name="PlannDocument" table="PLANN_DOCUMNET">
<key column="PLAN_ID"></key> //<<KEY IN JOINING TABLE BUT ALSO ID IN THIS TABLE
<one-to-many class="DocsysHoldingDoc"/>
</set>
</class>
PlannDocument HBM XML
<class name="PlannDocument" abstract="true" table="PLANN_DOCUMNET">
<id name="PlanId" column="PLAN_ID" type = "int">
<generator class="assigned"/>
</id>
<property name="DocId" column="DOC_ID" />
<property name="DocName" column="DOC_NAME" />
<property name="DocType" column="DOC_TYPE" />
<many-to-one name="Plann" column="PLAN_ID"></many-to-one>
</class>
ERROR: NHibernate.MappingException: 'Unable to build the insert statement for class <>.PlannDocument: a failure occurred when adding the Id of the class'
ArgumentException: The column 'PLAN_ID' has already been added in this SQL builder Parameter name: columnName
Am I doing something wrong here?
回答1:
Based on your comments (under deleted answer), name of primary key column in both the tables is same - i.e. PLAN_ID
. You want to join these two tables based on many-to-one relation.
The problem here is that the same column name (from two different tables) is being added twice in the mapping.
That is why the error:
ERROR: NHibernate.MappingException: 'Unable to build the insert statement for class <>.PlannDocument: a failure occured when adding the Id of the class'
ArgumentException: The column 'PLAN_ID' has already been added in this SQL builder Parameter name: columnName
In PlannDocument HBM, column name PLAN_ID
is first used while creating id
as below:
<id name="PlanId" column="PLAN_ID" type = "int">
and then, again while creating many-to-one
relation as below:
<many-to-one name="Plann" column="PLAN_ID"></many-to-one>
This is causing conflict of column name.
The solution I can think is to change the column name to something defer from the other table. Also, modify the classes and mappings accordingly.
I understand that this cannot be the solution every time and in all the conditions.
回答2:
If you have the same column for identifier
and for your desired many-to-one
association - it's not really a many-to-one
association. Sharing the same identifier
means it's one-to-one
association. Just use it instead of your many-to-one
mapping in PlannDocument.hbm.xml and it should work:
<one-to-one name="Plann" constrained="true" />
If your PlannDocument.Plann
can be null than use constrained="false"
instead. But be aware that this will cost you additional query to check if Plann
really exists.
来源:https://stackoverflow.com/questions/55171918/many-to-many-with-same-id-key-fields