Many to many relationship problem
Hi folks!
I am having the following problem when mapping many-to-many relationships: "More than one writable many-to-many mapping cannot use the same relation table".
This is what I am doing: I have a class Person and a class Meeting. One Person has many meetings and one Meeting has many participants (person).
I did the M-to-M relationship for the class Person and it worked fine in the workbench. But when I tried to do it in the Meeting class the workbench complained with that error.
I believe it might be a problem with the source and target references but I couldn't figure out how to solve it.
If I check in the intermediate table there are only 2 references created.
Can anyone help?
Hello,
Firstly, think about object model consistency (without TopLink or other persistence layer at all): should you be changing one side (eg Person), adding a meeting, without changing the other side? Is that object model self-consistent? It doesn't appear so to me- I can navigate from meeting to person and not get the same results as navigating from person to meeting. All this is irrespective of the persistence layer.
TopLink, first and foremost, expects that your object model is self-consistent. If it is, then you will find that the problem you indicate is no longer a problem- if i update a person with a new meeting, i change the meeting to person relationship as well. This means that although one direction is read-only to TopLink, the other is not- so the data will be written.
I hope this helps,
Christian
Similar Messages
-
One-to-many relationship: problem with several tables on the one side...
Hello
I'm having problems developing a database for a content management system. Apart from details, I've got one main table, that holds the tree structure of the content ("resources") and several other tables that contain data of a particular datatype ("documents", "images", etc.). Now, there's one-to-many relationship between "resources" table and all the datatype tables - that is, in the "resources" table there's "resource_id" column, being a foreign key referenced to the "id" columns in the datatype tables.
The problem is that this design is deficient. I can't tell form the "resource_id" column from which datatype table to get the data. It seems to me that one-to-many relationship only works with two tables. If the data on the one side of the relationship is contained in several tables, problems arise.
Anybody knows a solution? I would be obliged.
Regards
HavocadoHi;
A simple way may be create a view on referenced tables:
Connected to Oracle Database 10g Express Edition Release 10.2.0.1.0
Connected as hr
SQL>
SQL> drop table resources;
Table dropped
SQL> create table resources(id number, name varchar2(12));
Table created
SQL> insert into resources values(1,'Doc....');
1 row inserted
SQL> insert into resources values(2,'Img....');
1 row inserted
SQL> drop table documents;
Table dropped
SQL> create table documents(id number, resource_id number,type varchar2(12));
Table created
SQL> insert into documents values(1,1,'txt');
1 row inserted
SQL> drop table images;
Table dropped
SQL> create table images(id number, resource_id number,path varchar2(24));
Table created
SQL> insert into images values(1,2,'/data01/images/img01.jpg');
1 row inserted
SQL> create or replace view vw_resource_ref as
2 select id, resource_id, type, null as path from documents
3 union
4 select id, resource_id, null as type, path from images;
View created
SQL> select * from resources r inner join vw_resource_ref rv on r.id = rv.resource_id;
ID NAME ID RESOURCE_ID TYPE PATH
1 Doc.... 1 1 txt
2 Img.... 1 2 /data01/images/img01.jpg
SQL> Regards.... -
One-to-many relationships problem
Hi,
I'm having some problems with one-to-many relationships.
I've a two way relationship beetwen Person and Document.
Person has a collection of Documents (1-n).
Document has an instance for Person.
In my database schema Document has a FK for person.
The problem occurs when I'm trying to save the Person object
with a collection of Documents.
Oracle gives me the following message:
ORA-00001: unique constraint (SMS.PK_PERSON) violated
In my kodo.properties file I put:
kodo.jdbc.ForeignKeyConstraints: true
It seems that when the collection of Documents is persisted, kodo tries to
save a new Person object for each Document.
When I have just one instance of Document in my collection kodo persists
it ok, but when I have move instances I get
that problem.
Can somebody help me?
Thanks in advance,
Joan CaffeeYou need to make sure each Document references the same Person object in
the JVM. JDO persists your object model as-is. Each distinct JVM
object becomes a distinct database record. You can't have multiple JVM
objects in the same PersistenceManager representing the same database
record. -
Aggregate one-to-many relationship problem
Hello,
After migrating from Toplink 9i I've stumbled across a problem with our aggregate objects.
Toplink Workbench reports no errors and generates a nice XML but in runtime I get this error whenever a aggregate function is used.
[TopLink fin]: 2008.02.13 03:18:11.552--ServerSession(12626425)--Connection(29948747)--Thread(Thread[main,5,main])--SELECT DISTINCT t0.NPL_PACK_ID, t0.NPL_ID FROM NPL_MEDPROD t3, FASS_MEDPROD t2, NPL_MEDPROD t1, NPL_PACKAGE t0 WHERE (((t0.NPL_ID = t1._Presentation->NPL_ID_IN_REFERENCE_NPL_PACKAGE_NPL_MEDPROD_Test) AND ((t1.NPL_ID = t2.NPL_ID) AND (t3.NPL_ID LIKE '19750613000031%'))) AND (t3.NPL_ID = t2.NPL_ID))
Caused by: Undantag [TOPLINK-4002] (Oracle TopLink - 10g Release 3 (10.1.3.1.0) (Build 061004)): oracle.toplink.exceptions.DatabaseException
Internt undantag: java.sql.SQLException: ORA-00911: invalid character
Felkod: 911
I belive that problem resides in this clause :
t1._Presentation->NPL_ID_IN_REFERENCE_NPL_PACKAGE_NPL_MEDPROD_Test
I've created a small test project with just a couple of classes but the same aggregate problem occurs which has let me to believe the problem does not come from the migrating process which was my first guess. If anyone could help me discover what I am doing wrong it would be very appreciated. Below is my test project output.
<?xml version="1.0" encoding="UTF-8"?>
<toplink:object-persistence version="Oracle TopLink - 10g Release 3 (10.1.3.1.0) (Build 061004)" xmlns:opm="http://xmlns.oracle.com/ias/xsds/opm" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:toplink="http://xmlns.oracle.com/ias/xsds/toplink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
<opm:name>test</opm:name>
<opm:class-mapping-descriptors>
<opm:class-mapping-descriptor xsi:type="toplink:relational-class-mapping-descriptor">
<opm:class>se.lif.fass.fassdata.impl.FASSMedProdImpl</opm:class>
<opm:alias>FASSMedProdImpl</opm:alias>
<opm:primary-key>
<opm:field table="FASS_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
</opm:primary-key>
<opm:events xsi:type="toplink:event-policy"/>
<opm:querying xsi:type="toplink:query-policy"/>
<opm:attribute-mappings>
<opm:attribute-mapping xsi:type="toplink:one-to-one-mapping">
<opm:attribute-name>_Medprod</opm:attribute-name>
<opm:reference-class>schemas_npl.instance.impl.MedprodTypeImpl</opm:reference-class>
<opm:private-owned>true</opm:private-owned>
<opm:foreign-key>
<opm:field-reference>
<opm:source-field table="FASS_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
<opm:target-field table="NPL_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
</opm:field-reference>
</opm:foreign-key>
<opm:foreign-key-fields>
<opm:field table="FASS_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
</opm:foreign-key-fields>
<toplink:batch-reading>true</toplink:batch-reading>
<toplink:selection-query xsi:type="toplink:read-object-query"/>
</opm:attribute-mapping>
<opm:attribute-mapping xsi:type="toplink:direct-mapping">
<opm:attribute-name>id</opm:attribute-name>
<opm:read-only>true</opm:read-only>
<opm:field table="FASS_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
</opm:attribute-mapping>
</opm:attribute-mappings>
<toplink:descriptor-type>independent</toplink:descriptor-type>
<toplink:instantiation/>
<toplink:copying xsi:type="toplink:instantiation-copy-policy"/>
<toplink:change-policy xsi:type="toplink:deferred-detection-change-policy"/>
<toplink:tables>
<toplink:table name="FASS_MEDPROD"/>
</toplink:tables>
</opm:class-mapping-descriptor>
<opm:class-mapping-descriptor xsi:type="toplink:relational-class-mapping-descriptor">
<opm:class>schemas_npl.instance.impl.MedprodTypeImpl</opm:class>
<opm:alias>MedprodTypeImpl</opm:alias>
<opm:primary-key>
<opm:field table="NPL_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
</opm:primary-key>
<opm:events xsi:type="toplink:event-policy"/>
<opm:querying xsi:type="toplink:query-policy"/>
<opm:attribute-mappings>
<opm:attribute-mapping xsi:type="toplink:aggregate-object-mapping">
<opm:attribute-name>_Medprodpack</opm:attribute-name>
<toplink:reference-class>schemas_npl.instance.impl.MedprodTypeImpl$MedprodpackTypeImpl</toplink:reference-class>
<toplink:allow-null>false</toplink:allow-null>
<toplink:field-translations>
<toplink:field-translation>
<toplink:source-field name="_Presentation->NPL_ID_IN_REFERENCE_NPL_PACKAGE_NPL_MEDPROD_Test" xsi:type="opm:column"/>
<toplink:target-field table="NPL_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
</toplink:field-translation>
</toplink:field-translations>
</opm:attribute-mapping>
<opm:attribute-mapping xsi:type="toplink:direct-mapping">
<opm:attribute-name>_Nplid</opm:attribute-name>
<opm:field table="NPL_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
</opm:attribute-mapping>
<opm:attribute-mapping xsi:type="toplink:direct-mapping">
<opm:attribute-name>id</opm:attribute-name>
<opm:read-only>true</opm:read-only>
<opm:field table="NPL_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
</opm:attribute-mapping>
</opm:attribute-mappings>
<toplink:descriptor-type>independent</toplink:descriptor-type>
<toplink:instantiation/>
<toplink:copying xsi:type="toplink:instantiation-copy-policy"/>
<toplink:change-policy xsi:type="toplink:deferred-detection-change-policy"/>
<toplink:tables>
<toplink:table name="NPL_MEDPROD"/>
</toplink:tables>
</opm:class-mapping-descriptor>
<opm:class-mapping-descriptor xsi:type="toplink:relational-class-mapping-descriptor">
<opm:class>schemas_npl.instance.impl.MedprodTypeImpl$MedprodpackTypeImpl</opm:class>
<opm:alias>MedprodTypeImpl$MedprodpackTypeImpl</opm:alias>
<opm:events xsi:type="toplink:event-policy"/>
<opm:querying xsi:type="toplink:query-policy"/>
<opm:attribute-mappings>
<opm:attribute-mapping xsi:type="toplink:one-to-many-mapping">
<opm:attribute-name>_Presentation</opm:attribute-name>
<opm:reference-class>schemas_npl.instance.impl.MedprodTypeImpl$MedprodpackTypeImpl$PresentationTypeImpl</opm:reference-class>
<opm:private-owned>true</opm:private-owned>
<opm:target-foreign-key>
<opm:field-reference>
<opm:source-field table="NPL_PACKAGE" name="NPL_ID" xsi:type="opm:column"/>
<opm:target-field name="_Presentation->NPL_ID_IN_REFERENCE_NPL_PACKAGE_NPL_MEDPROD_Test" xsi:type="opm:column"/>
</opm:field-reference>
</opm:target-foreign-key>
<toplink:batch-reading>true</toplink:batch-reading>
<toplink:container xsi:type="toplink:list-container-policy">
<toplink:collection-type>com.sun.xml.bind.util.ListImpl</toplink:collection-type>
</toplink:container>
<toplink:selection-query xsi:type="toplink:read-all-query">
<toplink:container xsi:type="toplink:list-container-policy">
<toplink:collection-type>com.sun.xml.bind.util.ListImpl</toplink:collection-type>
</toplink:container>
</toplink:selection-query>
</opm:attribute-mapping>
</opm:attribute-mappings>
<toplink:descriptor-type>aggregate</toplink:descriptor-type>
<toplink:instantiation/>
<toplink:copying xsi:type="toplink:instantiation-copy-policy"/>
<toplink:change-policy xsi:type="toplink:deferred-detection-change-policy"/>
</opm:class-mapping-descriptor>
<opm:class-mapping-descriptor xsi:type="toplink:relational-class-mapping-descriptor">
<opm:class>schemas_npl.instance.impl.MedprodTypeImpl$MedprodpackTypeImpl$PresentationTypeImpl</opm:class>
<opm:alias>MedprodTypeImpl$MedprodpackTypeImpl$PresentationTypeImpl</opm:alias>
<opm:primary-key>
<opm:field table="NPL_PACKAGE" name="NPL_PACK_ID" xsi:type="opm:column"/>
</opm:primary-key>
<opm:events xsi:type="toplink:event-policy"/>
<opm:querying xsi:type="toplink:query-policy"/>
<opm:attribute-mappings>
<opm:attribute-mapping xsi:type="toplink:direct-mapping">
<opm:attribute-name>_Nplpackid</opm:attribute-name>
<opm:field table="NPL_PACKAGE" name="NPL_PACK_ID" xsi:type="opm:column"/>
</opm:attribute-mapping>
<opm:attribute-mapping xsi:type="toplink:one-to-one-mapping">
<opm:attribute-name>backref</opm:attribute-name>
<opm:reference-class>schemas_npl.instance.impl.MedprodTypeImpl</opm:reference-class>
<opm:foreign-key>
<opm:field-reference>
<opm:source-field table="NPL_PACKAGE" name="NPL_ID" xsi:type="opm:column"/>
<opm:target-field table="NPL_MEDPROD" name="NPL_ID" xsi:type="opm:column"/>
</opm:field-reference>
</opm:foreign-key>
<opm:foreign-key-fields>
<opm:field table="NPL_PACKAGE" name="NPL_ID" xsi:type="opm:column"/>
</opm:foreign-key-fields>
<toplink:indirection xsi:type="toplink:value-holder-indirection-policy"/>
<toplink:selection-query xsi:type="toplink:read-object-query"/>
</opm:attribute-mapping>
<opm:attribute-mapping xsi:type="toplink:direct-mapping">
<opm:attribute-name>id</opm:attribute-name>
<opm:read-only>true</opm:read-only>
<opm:field table="NPL_PACKAGE" name="NPL_ID" xsi:type="opm:column"/>
</opm:attribute-mapping>
</opm:attribute-mappings>
<toplink:descriptor-type>independent</toplink:descriptor-type>
<toplink:instantiation/>
<toplink:copying xsi:type="toplink:instantiation-copy-policy"/>
<toplink:change-policy xsi:type="toplink:deferred-detection-change-policy"/>
<toplink:tables>
<toplink:table name="NPL_PACKAGE"/>
</toplink:tables>
</opm:class-mapping-descriptor>
</opm:class-mapping-descriptors>
<toplink:login xsi:type="toplink:database-login">
<toplink:platform-class>oracle.toplink.platform.database.oracle.Oracle8Platform</toplink:platform-class>
<toplink:user-name>fassadmin</toplink:user-name>
<toplink:password>3CC3773C96563CA0C89634305615359CD62D1A19DF561D1E</toplink:password>
<toplink:driver-class>oracle.jdbc.driver.OracleDriver</toplink:driver-class>
<toplink:connection-url>jdbc:oracle:oci8:@DB2</toplink:connection-url>
</toplink:login>
</toplink:object-persistence>
Regards
/JonasThe issue is in the one-to-many mapping in the aggregate,
<br>
<opm:attribute-mapping xsi:type="toplink:one-to-many-mapping">
<opm:attribute-name>_Presentation</opm:attribute-name>
<opm:reference-class>schemas_npl.instance.impl.MedprodTypeImpl$MedprodpackTypeImpl$PresentationTypeImpl</opm:reference-class>
<opm:private-owned>true</opm:private-owned>
<opm:target-foreign-key>
<opm:field-reference>
<opm:source-field table="NPL_PACKAGE" name="NPL_ID" xsi:type="opm:column"/>
<opm:target-field name="_Presentation->NPL_ID_IN_REFERENCE_NPL_PACKAGE_NPL_MEDPROD_Test" xsi:type="opm:column"/>
</opm:field-reference>
</opm:target-foreign-key>There is an issue with the Mapping Workbench and shared aggregates with one-to-many mappings and translating the foreign key fields. Did this work before, I would be surprized if it did, unless the 2.5 Builder was used?
Anyway the easiest workaround is to either edit the XML and change the NPL_ID_IN_REFERENCE_NPL_PACKAGE_NPL_MEDPROD_Test column name to what it should be, or define a descriptor amendment method to define the one-to-many mapping with the correct field names.
-- James : EclipseLink -
Problem with 1-to-many relationship between entity beans
Hi All!
I have two tables TMP_GROUP and TMP_EMPLOYEE with following fields:
TMP_GROUP: ID, CAPTION, COMMENT, STATUS.
TMP_EMPLOYEE: ID, LOGIN, GROUP_ID.
For this tables i create two entity beans GROUP and EMPLOYEE respectively.
The relationship looks like this
descriptor ejb.xml:
<ejb-relation>
<description>description</description>
<ejb-relation-name>employeesOfGroup</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>com.mypackage.GroupBean</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>GroupBean</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>employees</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>com.mypackage.EmployeeBean</ejb-relationship-role-name>
<multiplicity>Many</multiplicity>
<relationship-role-source>
<ejb-name>EmployeeBean</ejb-name>
</relationship-role-source>
</ejb-relationship-role>
</ejb-relation>
descriptor persistent.xml:
<table-relation>
<table-relationship-role
key-type="PrimaryKey">
<ejb-name>GroupBean</ejb-name>
<cmr-field>employees</cmr-field>
</table-relationship-role>
<table-relationship-role
key-type="NoKey">
<ejb-name>EmployeeBean</ejb-name>
<fk-column>
<column-name>GROUP_ID</column-name>
<pk-field-name>ejb_pk</pk-field-name>
</fk-column>
</table-relationship-role>
</table-relation>
Now i implement business method:
public Long addEmployee(String login, long groupId) {
Long result;
try {
EmployeeLocal employee = employeeHome.create(login);
GroupLocal group =
groupHome.findByPrimaryKey(new Long(groupId));
Collection employees = group.getEmployees();
employees.add(employee);
result = (Long) employee.getPrimaryKey();
} catch (CreateException ex) {
result = new Long(0);
} catch (FinderException ex) {
result = new Long(0);
return result;
When i call this method from web service, the following exception is raised:
com.sap.engine.services.ejb.exceptions.BaseTransactionRolledbackLocalException: Exception in method com.mypackage.GroupLocalHomeImpl0.findByPrimaryKey(java.lang.Object).
P.S.
1) I have transaction attribute set to "Required" for all methods of all beans
2) I have unique index for each table:
TMP_GROUP_I1: CAPTION
TMP_EMPLOYEE_I1: LOGIN (however i think GROUP_ID must be added here too)
3) I tried many:many relationship with this tables and it works fine
4) I try another implementation of addEmployee method with
EmployeeLocal employee = employeeHome.create(login, groupId);
without using GroupLocal cmr-field and GroupLocalHome findByPrimaryKey method, the result is same error.
Can somebody help me with this problem?
Thanks in advance.
Best regards, Abramov Andrey.gimbal2 wrote:
1: The @JoinColumn on the listOfDepartments collection in Company is wrong. It should be something like this for a bidirectional relationship:
@OneToMany(mappedBy="company") // company is the matching property name in Department
private List <Department> listOfDepartment = new ArrayList<Department>();Note that I removed the fetch configuration; onetomany is fetched lazy by design. Saves some clutter eh.
2: use a Set in stead of a List (hibernate doesn't like lists much in entities and will break when you create slightly more complex entity relations)
3: don't just slap cascades on collections, especially of type ALL. Do it with care. In the many years I've been using JPA I've only had to cascade deletes in very specific situations, maybe once or twice. I never needed any of the other cascade types, they just invite sloppy code if you ask me. When working with persistence you should apply a little precision.I made all changes as you mentioned but still compID in department table shows null value... -
Problem with 1:many relationship between entity beans.
Hi All!
I have two tables TMP_GROUP and TMP_EMPLOYEE with following fields:
TMP_GROUP: ID, CAPTION, COMMENT, STATUS.
TMP_EMPLOYEE: ID, LOGIN, GROUP_ID.
For this tables i create two entity beans GROUP and EMPLOYEE respectively.
The relationship looks like this
descriptor ejb.xml:
<ejb-relation>
<description>description</description>
<ejb-relation-name>employeesOfGroup</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>com.mypackage.GroupBean</ejb-relationship-role-name>
<multiplicity>One</multiplicity>
<relationship-role-source>
<ejb-name>GroupBean</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>employees</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>com.mypackage.EmployeeBean</ejb-relationship-role-name>
<multiplicity>Many</multiplicity>
<relationship-role-source>
<ejb-name>EmployeeBean</ejb-name>
</relationship-role-source>
</ejb-relationship-role>
</ejb-relation>
descriptor persistent.xml:
<table-relation>
<table-relationship-role
key-type="PrimaryKey">
<ejb-name>GroupBean</ejb-name>
<cmr-field>employees</cmr-field>
</table-relationship-role>
<table-relationship-role
key-type="NoKey">
<ejb-name>EmployeeBean</ejb-name>
<fk-column>
<column-name>GROUP_ID</column-name>
<pk-field-name>ejb_pk</pk-field-name>
</fk-column>
</table-relationship-role>
</table-relation>
Now i implement business method:
public Long addEmployee(String login, long groupId) {
Long result;
try {
EmployeeLocal employee = employeeHome.create(login);
GroupLocal group =
groupHome.findByPrimaryKey(new Long(groupId));
Collection employees = group.getEmployees();
employees.add(employee);
result = (Long) employee.getPrimaryKey();
} catch (CreateException ex) {
result = new Long(0);
} catch (FinderException ex) {
result = new Long(0);
return result;
When i call this method from web service, the following exception is raised:
com.sap.engine.services.ejb.exceptions.BaseTransactionRolledbackLocalException: Exception in method com.mypackage.GroupLocalHomeImpl0.findByPrimaryKey(java.lang.Object).
P.S.
1) I have transaction attribute set to "Required" for all methods of all beans
2) I have unique index for each table:
TMP_GROUP_I1: CAPTION
TMP_EMPLOYEE_I1: LOGIN (however i think GROUP_ID must be added here too)
3) I tried many:many relationship with this tables and it works fine
4) I try another implementation of addEmployee method with
EmployeeLocal employee = employeeHome.create(login, groupId);
without using GroupLocal cmr-field and GroupLocalHome findByPrimaryKey method, the result is same error.
Can somebody help me with this problem?
Thanks in advance.
Best regards, Abramov Andrey.I have posted excerpts from my orion-ejb-jar.xml file in this posting: Problem mapping a 1:M relationship between two entity EJBs w/ a compound PK
Sorry for the duplicate postings, but I was getting errors on the submission.
April -
Many-to-many relationship performance problem
Hi:
I have model that uses a bridge table to solve a many-to-many relationship. Here it is:
dimension 1 -< fact table >-dimension 2-< bridge table >-additional data table
Now, when I drive from the additional data table with a specific value and join to the bridge table and dimension 2, the performance is fine. But, as soon as I add the fact table to the query, the query never returns. I'm in a development environment, so my fact table has 220K records, and the bridge table has 200K records. The dimension 2 and additional data tables have hundreds of records. In other words, it's not much data. I have indexes and referential constraints on all relevant columns.
Can anyone suggest what is happening to cause such a performance hit when I add the fact table to the query?
Thanks for any suggestions!sybrand_b wrote:
The way you write it yes, but there is one minor detail.
You can have a 0,1 or many relationship: one employee has zero, one or many phone numbers
but you can not have the opposite, as it doesn't make sense.
0, 1 or many phone numbers belong to 1 employee.
It is customary to use 0,1 or m when the relationship is optional.
Sybrand Bakker
Senior Oracle DBAIs this correct now ?
one to many : one employee has 0,1 or multiple phone numbers
many to one : 1 or multiple phone numbers to one employee -
Hi,
I am haviing a crystal report problem. The problem relates to a one-to-many relationship involving two tables.
I have a similar setup to the following:
I have 2 database tables: table1 & table2
table1 consists of 3 fields:
{id#}, {yes/no},{up/down}
table2 consists of 2 fields:
{id#},
the field can contain any of the following values: 'open', 'closed', 'final', 'complete'.
The problem is that there exist many states to one id#.
I have a bar graph in my report that displays a bar for the count of the{yes/no} field and a bar for the count of the {up/down} field. I want also a bar for the count of when the field = 'final'.
What happens when I write a formula for the field in the second table and place it in the 'show values' section of the chart expert, is the count displayed in each bar on the graph increases significantly. I am assuming this is because there are multiple records in table 2 for each record in table 1.
What I want to happen is that the graph displays bar 1 and bar 2 correctly and then when I put in the formula for the third bar, it simply displays that bar with the count for when the field = 'final'. I dont want it to affect the whole garph.
Has anyone got any suggestions on how I can do this?
I have tried messing around with the distinct records setting in crystal and also by writing an sql query specifying DISTINCT keyword instead of using the select expert, but to no avail.
Please please can someone help me with this issue.
Thank you.
JYou can add a 1-1 query key through the code API in a descriptor amendment method. You could also define a selection criteria on the 1-m mapping to filter the type=2.
Example: (see Foundation Library manual 8-17)
OneToOneQueryKey queryKey = new OneToOneQueryKey();
queryKey.setName("organization");
queryKey.setReferenceClass(Organization.class);
ExpressionBuilder builder = new ExpressionBuilder();
queryKey.setJoinCriteria(builder.getField("ORGANIZATION.ORG_ID").equal(builder.getParameter("RELATIONSHIP.PARENT_ID").and(builder.getParamater("RELATIONSHIP.RELATIONSHIP_TYPE").equal(2)));
relationDescriptor.addQueryKey(queryKey);
Example: (of 1-m mapping with selection criteria)
OneToManyMapping mapping = new OneToManyMapping();
mapping.setReferenceClass(Relation.class);
mapping.setTargetForeignKey("RELATION.PARENT_ID");
ExpressionBuilder builder = new ExpressionBuilder();
mapping.setSelectionCriteria(builder.getField("RELATIONSHIP.PARENT_ID").equal(builder.getParameter("ORGANIZATION.ORG_ID").and(builder.getField("RELATIONSHIP.RELATIONSHIP_TYPE").equal(2)));
orgDescriptor.addMapping(mapping); -
Creating data in a many-to-many-relationship
Hello,
we really have problems in implementing a JClient dialog based on BC4J for creating data in a many to many relationship - especially with cascade delete on both sides.
Simplified our tables look like:
create table A_TABLE
A_ID VARCHAR2(5) not null,
A_NAME VARCHAR2(30) not null,
constraint PK_A_TABLE primary key (A_ID),
constraint UK_A_TABLE unique (A_NAME)
create table B_TABLE
B_ID VARCHAR2(5) not null,
B_NAME VARCHAR2(30) not null,
constraint PK_B_TABLE primary key (B_ID),
constraint UK_B_TABLE unique (B_NAME)
create table AB_TABLE
A_ID VARCHAR2(5) not null,
B_ID VARCHAR2(5) not null,
constraint PK_AB_TABLE primary key (A_ID, B_ID),
constraint FK_AB_A foreign key (A_ID) references A_TABLE (A_ID) on delete cascade,
constraint FK_AB_B foreign key (B_ID) references B_TABLE (B_ID) on delete cascade
Could JDev Team please provide a BC4J/JClient sample that performs the following task:
The dialog should use A_TABLE as master and AB_TABLE as detail. The detail displays the names associated with the IDs. Next to AB_TABLE should be a view of B_TABLE which only displays rows that are currently not in AB_TABLE. Two buttons are used for adding and removing rows in AB_TABLE. After adding or removing rows in the intersection the B_TABLE view should be updated. The whole thing should work in the middle and client tier. This means no database round trips after each add/remove, no posts for AB_TABLE and no query reexecution for B_TABLE until commit/rollback.
This is a very common szenario: For an item group (A_TABLE) one can select and deselect items (AB_TABLE) from a list of available items (B_TABLE). Most of JDeveloper4s wizards use this. They can handle multi/single selections, selections from complex structures like trees and so on. Ok, the wizards are not based on BC4J - or? How can we do it with BC4J?
Our main problems are:
1. Updating the view of B_TABLE after add/remove reflecting the current selection
2. A good strategy for displaying the names instead of the IDs (subqueries or joining the three tables)
3. A JBO-27101 DeadEntityAccessException when removing an existing row from AB_TABLE and adding it again
Other problems:
4. We get a JBO-25030 InvalidOwnerException when creating a row in AB_TABLE. This is caused by the composition. We workaround this using createAndInitRow(AttributeList) on the view object (instead of create()). This is our add-Action:
ViewObject abVO = panelBinding.getApplicationModule().findViewObject("ABView");
ViewObject bVO = panelBinding.getApplicationModule().findViewObject("BView");
Row bRow = bVO.getCurrentRow();
NameValuePairs attribList = new NameValuePairs(
new String[]{"BId"}, new Object[]{bRow.getAttribute("BId")});
Row newRow = abVO.createAndInitRow(attribList);
abVO.insertRow(newRow);
5. After inserting the new row the NavigationBar has enabled commit/rollback buttons and AB_TABLE displays the row. But performing a commit does nothing. With the following statement after insertRow(newRow) the new row is created in the database:
newRow.setAttribute("BId", bRow.getAttribute("BId"));
Please give us some help on this subject.
Best regards
Michael Thal<Another attempt to post a reply. >
Could JDev Team please provide a BC4J/JClient sample
that performs the following task:
The dialog should use A_TABLE as master and AB_TABLE
as detail. The detail displays the names associated
with the IDs. Next to AB_TABLE should be a view of
B_TABLE which only displays rows that are currently
not in AB_TABLE. Two buttons are used for adding and
removing rows in AB_TABLE. After adding or removing
rows in the intersection the B_TABLE view should be
updated. The whole thing should work in the middle
and client tier. This means no database round trips
after each add/remove, no posts for AB_TABLE and no
query reexecution for B_TABLE until commit/rollback.
This is a very common szenario: For an item group
(A_TABLE) one can select and deselect items
(AB_TABLE) from a list of available items (B_TABLE).
Most of JDeveloper4s wizards use this. They can
handle multi/single selections, selections from
complex structures like trees and so on. Ok, the
wizards are not based on BC4J - or? How can we do it
with BC4J?
Our main problems are:
1. Updating the view of B_TABLE after add/remove
reflecting the current selectionYou should be able to use insertRow() to insert the row into proper collection.
However to remove a row only from the collection, you need to add a method on the VO subclasses (and perhaps export this method so that the client side should see it) to unlink a row from a collection (but not remove the associated entities from the cache).
This new method should use ViewRowSetImpl.removeRowAt() method to remove the row entry at the given index from it's collection. Note that this is an absolute index and not a range index in the collection.
2. A good strategy for displaying the names instead
of the IDs (subqueries or joining the three tables)You should join the three tables by using reference (and perhaps readonly) entities.
3. A JBO-27101 DeadEntityAccessException when
removing an existing row from AB_TABLE and adding it
againThis is happening due to remove() method on the Row which is marking the row as removed. Attempts to add this row into another collection will throw a DeadEntityAccessException.
You may 'remove the row from it's collection, then call 'Row.refresh' on it to revert the entity back to undeleted state.
>
Other problems:
4. We get a JBO-25030 InvalidOwnerException when
creating a row in AB_TABLE. This is caused by the
composition. We workaround this using
createAndInitRow(AttributeList) on the view object
(instead of create()). This is our add-Action:
ViewObject abVO =
O =
panelBinding.getApplicationModule().findViewObject("AB
iew");
ViewObject bVO =
O =
panelBinding.getApplicationModule().findViewObject("BV
ew");
Row bRow = bVO.getCurrentRow();
NameValuePairs attribList = new NameValuePairs(
new String[]{"BId"}, new
String[]{"BId"}, new
Object[]{bRow.getAttribute("BId")});
Row newRow = abVO.createAndInitRow(attribList);
abVO.insertRow(newRow);This is a handy approach. Note that Bc4j framework does not support dual composition where the same detail can be owned by two or more masters. In those cases, you also need to implement post ordering to post the masters before the detail (and reverse ordering for deletes).
>
5. After inserting the new row the NavigationBar has
enabled commit/rollback buttons and AB_TABLE displays
the row. But performing a commit does nothing. With
the following statement after insertRow(newRow) the
new row is created in the database:
newRow.setAttribute("BId",
d", bRow.getAttribute("BId"));This bug in JDev 903 was fixed and a patch set (9.0.3.1) is (I believe) available now via MetaLink.
>
>
Please give us some help on this subject.
Best regards
Michael Thal -
In powerpivot we are facing problem in resolving the many-to-many relationship between tables.
Current table schema is:
Having 4 tables-
Bills - columns are- Bill No(primary key)
Billing Fee Table-Fee ID(primary key), Bill Type, Sub Bill Type
FeeList Table-FeeList ID(primary key),Fee ID(Foriegn Key to Billingble),
Bill No(Foriegn Key to Bills)
Payments Table-Pay ID(Primary Key), Bill No(Foriegn Key to Bills)
Bills is the primary table for Feelist Table
and Payments Table -Bill No is the primary key.
Billing Fee Table is primary table for FeeList Table -
Fee ID is the primary key.
To create a pivot table using Payments Table, I need
Bill Type and Sub Bill Type. Hence fetched from
Biling Fee Table to FeeList Table based on the
Fee ID column using RELATED function.
As FeeList Table and Payments Table is having duplicate
Bill Nos, it is not possible to get Bill Type and
Sub Bill Type to Payments Table. I am trying to use LOOKUPVALUE
function to get data based on the Bill No, as there is no direct relationship exists between these two tables.
I have tried using
=LOOKUPVALUE('FeeList Table'[Sub Bill Type], 'FeeList Table'[Bill No], 'Payments Table'[Bill No]) function. But
the lookupvalue function returns an error if a duplicate is found.
Error is as below:
Calculation error in column 'Payments Table'[Sub Bill Type]: A table of multiple values was supplied where a single value was expected.
Kindly assist to resolve this issue.
ThanksHi Rekha,
What should your LOOKUPVALUE return if multiple rows are found in the FeeListTable? By the way it should work if a really finds "duplicates" (i.e. multiple times the same return value) but fails if it returns multiple rows with different values.
If you for example would want to return the first entry that was found, you could try (have not checked in PP for typos):
CALCULATE(MIN('FeeList Table'[Sub Bill Type]),
FILTER('FeeList Table',
'FeeList Table'[Bill No] = 'Payments Table'[Bill No]
Edit: a very nice way to handle Many-to-Many relationships is explained here:
http://blog.gbrueckl.at/2012/05/resolving-many-to-many-relationships-leveraging-dax-cross-table-filtering/
Julian Wissel | BI for NAV @ http://en.navbi.com | Blog @ blog.navida.eu -
Many to many relationship mapping.
Hi
I have a basic question on how to create a good java class model (POJOs) based on the database model.
I Have to follwing tables
Table1 with columns as
ID1
name
description
Table2 with columns as
ID2
dateCreated ..etc.
Since there is a many to many relationship between table1 and table2
So to map that we have a table3 with columns
ID3
ID1 // fk table1
ID2 // fk table2
browserName
startTime
endTime
So when I create Java classes:
// corresponding to table 1
Class MyTable1
private Integer ID1;
private List ID2; // to map with the table2
// corresponding to table 2
Class MyTable2
private Integer ID2
private List ID1; // to map with table 1
In this way I can create my classes. Is this the best way to put it together.
And where to put the attributed specific to table3. Like the BrowserName and the StartTime and the EndTime.
Any suggestion please.
Thanks.Your names leave a lot to be desired. Let's start with an example. Suppose I have a problem involving employees and the tasks assigned to them. An employee may have any number of tasks assigned to them and a task can be assigned to any number of employees. The assignment itself has more attributes: when it was assigned, its priority and so on.
public interface Employee {
Long getId(); //etc...
Set<Assignment> getAssignments();
void setAssignments(Set<Assignment> assignments);
public interface Task {
Long getId(); //etc...
Set<Assignment> getAssignments();
void setAssignments(Set<Assignment> assignments);
public interface Assignment {
Long getId(); //etc...
Employee getEmployee();
void setEmployee(Employee employee);
Task getTask();
void setTask(Task task);
}This assumes you want to navigate in all directions: from an employee to their assignments, from a task to its assignments and from an assignment to it employee and task. -
Struggling with a one to many relationship in a sub-report
Post Author: Scott_tansley
CA Forum: General
I have a database schema as per below: tblENQUIRY tblDatasheets tblReportParasIRSID (PK) 1 --> & IRSID (FK) UID (PK)Attribute1 SHEETID (PK) 1 > & SHEETID (FK)Attribute2 Attribute1 LIST_ORDER tblStandardParasAttribute3 Attribute2 PARA_CODE (FK) & < 1 CODE (PK)etc... Attribute3 TEXT etc...
The PROBLEM I am a Crystal Reports Newbie, and having to work through things bit by bitu2026 I've managed to achieve quite a lot, but I'm totally stuck with this and would appreciate some help. I need to create a report (essentially a letter and some datasheets) around a one-to-many relationship, which I have managed to compile using a main report (for the one [tblENQUIRY]) and sub report (for the many [tblDatasheets]). Essentially I need a covering letter, then the u2018manyu2019 datasheets, and then a number of other pages (which are largely static text). I have created a main report which includes the covering letter, holds a subreport for the datasheets, and then contains the text for the additional pages. This all works fine, and I get the correct number of datasheets for each main report. My problem stems from the use of this sub report. This sub-report needs to hold some attribute values for each datasheet, which is fine. However, on each datasheet page I need to have some paragraphs, which are held in another one to many relationship. Each datasheet may have up to six paragraphs held as a code in tblReportParas, with a relationship to the text as held in tblStandardParas. My original thought would have been to embed another sub report, containing the values from tblStandardParas!TEXT, into the first sub report. However, I have found that it is not possible to have a sub-report inside another sub-report. I had seperated the first sub-report out from the main report, and then embedded another sub-report into it. This worked fine until I tried to stitch the sub-report back into the main report (at which point the sub-sub-report dissapeared from view). I have therefore reworked my sub-report a little, and the attribution is now stored in a pageheader, with the tblStandardParas!TEXT in a detail section below it. This almost works! The only problem is that there is no relationship between the pageheader and detail sections. To clarify, I would expect to have one datasheet, with the attribution at the top, and then the six paras below. Then, the same on the next page (assuming there is a second datasheet) for that report. Instead, I get the correct attribution, but the detail section actually gives every paragraph in the database, no matter which datasheet/or report it related to! I therefore need to limit the detail section to only show those paragraphs where the SHEETID in tblReportParas is the same as the tblDatasheets SHEETID. Any offers of advice would be appreciated.Post Author: Scott_tansley
CA Forum: General
I managed to resolve this myself in the end. I moves the tblEnquiry data into report header/footer sections, this allowed me to add the tblDatasheets information into the details section, which gave me multiple pages - and then finally, the Paragraphs were added through the use of a sub report.
There's probably an even better way, but for now it works, it's quick - and so I'm going to go with it!
Thanks for your interest. -
Defining a many-to-many relationship with CMP EJBs : does it work for you
Curious to know whether someone has been able to set up a many to many relationship between two entity beans.
I have been struggling with this for days now and I can't get it to work.
In my test project I have two entity beans, resp. Consultant and Solution.
Consultant has a cmr field called 'solutions', which is a collection object from the opposite side (Solution).
This is the source of the ejb-jar.xml file
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE ejb-jar PUBLIC "-//Sun Microsystems, Inc.//DTD Enterprise JavaBeans 2.0//EN" "http://java.sun.com/dtd/ejb-jar_2_0.dtd">
<ejb-jar>
<description>EJB JAR description</description>
<display-name>EJB JAR</display-name>
<enterprise-beans>
<session>
<ejb-name>ProfilerBean</ejb-name>
<home>com.atosorigin.tcc.testing.ejbses.profiling.ProfilerHome</home>
<remote>com.atosorigin.tcc.testing.ejbses.profiling.Profiler</remote>
<local-home>com.atosorigin.tcc.testing.ejbses.profiling.ProfilerLocalHome</local-home>
<local>com.atosorigin.tcc.testing.ejbses.profiling.ProfilerLocal</local>
<ejb-class>com.atosorigin.tcc.testing.ejbses.profiling.ProfilerBean</ejb-class>
<session-type>Stateless</session-type>
<transaction-type>Container</transaction-type>
<ejb-local-ref>
<ejb-ref-name>EJBTesting/Solution</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>com.atosorigin.tcc.testing.ejbcmp.profiling.SolutionLocalHome</local-home>
<local>com.atosorigin.tcc.testing.ejbcmp.profiling.SolutionLocal</local>
<ejb-link>SolutionBean</ejb-link>
</ejb-local-ref>
<ejb-local-ref>
<ejb-ref-name>EJBTesting/Consultant</ejb-ref-name>
<ejb-ref-type>Entity</ejb-ref-type>
<local-home>com.atosorigin.tcc.testing.ejbcmp.profiling.ConsultantLocalHome</local-home>
<local>com.atosorigin.tcc.testing.ejbcmp.profiling.ConsultantLocal</local>
<ejb-link>ConsultantBean</ejb-link>
</ejb-local-ref>
</session>
<entity>
<ejb-name>ConsultantBean</ejb-name>
<home>com.atosorigin.tcc.testing.ejbcmp.profiling.ConsultantHome</home>
<remote>com.atosorigin.tcc.testing.ejbcmp.profiling.Consultant</remote>
<local-home>com.atosorigin.tcc.testing.ejbcmp.profiling.ConsultantLocalHome</local-home>
<local>com.atosorigin.tcc.testing.ejbcmp.profiling.ConsultantLocal</local>
<ejb-class>com.atosorigin.tcc.testing.ejbcmp.profiling.ConsultantBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>Consultant</abstract-schema-name>
<cmp-field>
<field-name>firstname</field-name>
</cmp-field>
<cmp-field>
<field-name>lastname</field-name>
</cmp-field>
<cmp-field>
<field-name>country</field-name>
</cmp-field>
<cmp-field>
<field-name>id</field-name>
</cmp-field>
<primkey-field>id</primkey-field>
<query>
<query-method>
<method-name>findBySolution</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>SELECT Object(c) FROM Consultant AS c,
IN(c.solutions) s WHERE s.id = ?1 </ejb-ql>
</query>
</entity>
<entity>
<ejb-name>SolutionBean</ejb-name>
<home>com.atosorigin.tcc.testing.ejbcmp.profiling.SolutionHome</home>
<remote>com.atosorigin.tcc.testing.ejbcmp.profiling.Solution</remote>
<local-home>com.atosorigin.tcc.testing.ejbcmp.profiling.SolutionLocalHome</local-home>
<local>com.atosorigin.tcc.testing.ejbcmp.profiling.SolutionLocal</local>
<ejb-class>com.atosorigin.tcc.testing.ejbcmp.profiling.SolutionBean</ejb-class>
<persistence-type>Container</persistence-type>
<prim-key-class>java.lang.String</prim-key-class>
<reentrant>False</reentrant>
<cmp-version>2.x</cmp-version>
<abstract-schema-name>Solution</abstract-schema-name>
<cmp-field>
<field-name>description</field-name>
</cmp-field>
<cmp-field>
<field-name>name</field-name>
</cmp-field>
<cmp-field>
<field-name>parent</field-name>
</cmp-field>
<cmp-field>
<field-name>id</field-name>
</cmp-field>
<primkey-field>id</primkey-field>
<query>
<query-method>
<method-name>findChildSolutions</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
</query-method>
<ejb-ql>SELECT Object(s) FROM Solution AS s WHERE
s.parent = ?1</ejb-ql>
</query>
<query>
<query-method>
<method-name>findTopLevelSolutions</method-name>
<method-params/>
</query-method>
<ejb-ql>Select Object(s) FROM Solution AS s WHERE
(s.parent = 'none')</ejb-ql>
</query>
</entity>
</enterprise-beans>
<relationships>
<ejb-relation>
<description>A consultant may have one or more areas of expertise</description>
<ejb-relation-name>Consultant_Solutions</ejb-relation-name>
<ejb-relationship-role>
<ejb-relationship-role-name>com.atosorigin.tcc.testing.ejbcmp.profiling.ConsultantBean</ejb-relationship-role-name>
<multiplicity>Many</multiplicity>
<relationship-role-source>
<ejb-name>ConsultantBean</ejb-name>
</relationship-role-source>
<cmr-field>
<cmr-field-name>solutions</cmr-field-name>
<cmr-field-type>java.util.Collection</cmr-field-type>
</cmr-field>
</ejb-relationship-role>
<ejb-relationship-role>
<ejb-relationship-role-name>com.atosorigin.tcc.testing.ejbcmp.profiling.SolutionBean</ejb-relationship-role-name>
<multiplicity>Many</multiplicity>
<relationship-role-source>
<ejb-name>SolutionBean</ejb-name>
</relationship-role-source>
</ejb-relationship-role>
</ejb-relation>
</relationships>
<assembly-descriptor>
<container-transaction>
<description>container-transaction</description>
<method>
<ejb-name>SolutionBean</ejb-name>
<method-name>*</method-name>
</method>
<method>
<ejb-name>ProfilerBean</ejb-name>
<method-name>*</method-name>
</method>
<method>
<ejb-name>ConsultantBean</ejb-name>
<method-name>*</method-name>
</method>
<trans-attribute>Required</trans-attribute>
</container-transaction>
</assembly-descriptor>
</ejb-jar>
I created a stateless session bean as a business facade for the two entity beans. I then created a webservice to test the beans.
What works :
- create a consultant
- get a consultant
- create a solution
- get a solution
(basically everything that doesn't involve the relationship field.
However, what doesn't work is the method call assignSolution:
- assign solution : this is implemented as follows
Business Method.
public void assignSolution(String consultantID, String solutionID)
throws ProfilingException {
// TODO : Implement
ConsultantLocal cons = null;
SolutionLocal sol = null;
try {
cons = consHome.findByPrimaryKey(consultantID);
sol = solHome.findByPrimaryKey(solutionID);
Collection solutions = cons.getSolutions();
solutions.add(sol);
//sol.getConsultants().add(cons);
} catch (FinderException ex) {
ex.printStackTrace();
throw new ProfilingException("failed to retrieve data from DB", ex);
As you can see I am trying to use the CM Relationship in this methhod. Adding the solution to a consultant should be as simple as adding a solution object to the collection retrieved with the getSolutions accessor. The Container is expected to persist the information in my MAXDB database.
However this doesn't happen.
The ORM details as defined in the persistent.xml follows :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE persistent-ejb-map SYSTEM "persistent.dtd">
<persistent-ejb-map>
<locking
type="Table"/>
<db-properties>
<data-source-name>TCC_PORTAL_PROFILER</data-source-name>
<database-vendor
name="SAPDB"/>
</db-properties>
<entity-beans>
<entity-bean>
<ejb-name>ConsultantBean</ejb-name>
<table-name>PFL_CONSULTANTS</table-name>
<field-map
key-type="NoKey">
<field-name>firstname</field-name>
<column>
<column-name>FIRSTNAME</column-name>
</column>
</field-map>
<field-map
key-type="NoKey">
<field-name>lastname</field-name>
<column>
<column-name>LASTNAME</column-name>
</column>
</field-map>
<field-map
key-type="NoKey">
<field-name>country</field-name>
<column>
<column-name>COUNTRY</column-name>
</column>
</field-map>
<field-map
key-type="PrimaryKey">
<field-name>id</field-name>
<column>
<column-name>ID</column-name>
</column>
</field-map>
<finder-descriptor>
<method-name>findBySolution</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
<load-selected-objects
lock="read"/>
</finder-descriptor>
</entity-bean>
<entity-bean>
<ejb-name>SolutionBean</ejb-name>
<table-name>PFL_SAPSOLUTIONS</table-name>
<field-map
key-type="NoKey">
<field-name>description</field-name>
<column>
<column-name>DESCRIPTION</column-name>
</column>
</field-map>
<field-map
key-type="NoKey">
<field-name>name</field-name>
<column>
<column-name>NAME</column-name>
</column>
</field-map>
<field-map
key-type="NoKey">
<field-name>parent</field-name>
<column>
<column-name>PARENTID</column-name>
</column>
</field-map>
<field-map
key-type="PrimaryKey">
<field-name>id</field-name>
<column>
<column-name>ID</column-name>
</column>
</field-map>
<finder-descriptor>
<method-name>findChildSolutions</method-name>
<method-params>
<method-param>java.lang.String</method-param>
</method-params>
<load-selected-objects
lock="read"/>
</finder-descriptor>
<finder-descriptor>
<method-name>findTopLevelSolutions</method-name>
<method-params/>
<load-selected-objects
lock="read"/>
</finder-descriptor>
</entity-bean>
</entity-beans>
<relationships>
<table-relation>
<help-table>PFL_CONS_SOL_MAP</help-table>
<table-relationship-role
key-type="PrimaryKey">
<ejb-name>ConsultantBean</ejb-name>
<cmr-field>solutions</cmr-field>
<fk-column>
<column-name>CONSULTANTID</column-name>
<pk-field-name>id</pk-field-name>
</fk-column>
</table-relationship-role>
<table-relationship-role
key-type="PrimaryKey">
<ejb-name>SolutionBean</ejb-name>
<fk-column>
<column-name>SOLUTIONID</column-name>
<pk-field-name>id</pk-field-name>
</fk-column>
</table-relationship-role>
</table-relation>
</relationships>
</persistent-ejb-map>
The error in the default trace file when calling the method states, there is an "inconsistency in the number of primary keys". Details follow.
#1.5#000F1F188E5C004400000000000010480003E76C80EFD57A#1098880364327#com.sap.engine.services.ejb#com.atosorigin.tcc/EJBCMPProfilingTest#com.sap.engine.services.ejb#Guest#2####4d2b2370281411d9a40d000f1f188e5c#SAPEngine_Application_Thread[impl:3]_31##0#0#Error##Java###
[EXCEPTION]
#1#com.sap.engine.services.ejb.exceptions.BaseRemoteException: Exception in method assignSolution.
at com.atosorigin.tcc.testing.ejbses.profiling.ProfilerObjectImpl0.assignSolution(ProfilerObjectImpl0.java:822)
at com.atosorigin.tcc.testing.ejbses.profiling.Profiler_Stub.assignSolution(Profiler_Stub.java:533)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at com.sap.engine.services.ejb.session.stateless_sp5.ObjectStubProxyImpl.invoke(ObjectStubProxyImpl.java:187)
at $Proxy73.assignSolution(Unknown Source)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:324)
at com.sap.engine.services.webservices.runtime.EJBImplementationContainer.invokeMethod(EJBImplementationContainer.java:126)
at com.sap.engine.services.webservices.runtime.RuntimeProcessor.process(RuntimeProcessor.java:146)
at com.sap.engine.services.webservices.runtime.RuntimeProcessor.process(RuntimeProcessor.java:68)
at com.sap.engine.services.webservices.runtime.servlet.ServletDispatcherImpl.doPost(ServletDispatcherImpl.java:92)
at SoapServlet.doPost(SoapServlet.java:51)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:760)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:853)
at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.runServlet(HttpHandlerImpl.java:385)
at com.sap.engine.services.servlets_jsp.server.HttpHandlerImpl.handleRequest(HttpHandlerImpl.java:263)
at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:339)
at com.sap.engine.services.httpserver.server.RequestAnalizer.startServlet(RequestAnalizer.java:317)
at com.sap.engine.services.httpserver.server.RequestAnalizer.invokeWebContainer(RequestAnalizer.java:810)
at com.sap.engine.services.httpserver.server.RequestAnalizer.handle(RequestAnalizer.java:238)
at com.sap.engine.services.httpserver.server.Client.handle(Client.java:92)
at com.sap.engine.services.httpserver.server.Processor.request(Processor.java:147)
at com.sap.engine.core.service630.context.cluster.session.ApplicationSessionMessageListener.process(ApplicationSessionMessageListener.java:37)
at com.sap.engine.core.cluster.impl6.session.UnorderedChannel$MessageRunner.run(UnorderedChannel.java:71)
at com.sap.engine.core.thread.impl3.ActionObject.run(ActionObject.java:37)
at java.security.AccessController.doPrivileged(Native Method)
at com.sap.engine.core.thread.impl3.SingleThread.execute(SingleThread.java:94)
at com.sap.engine.core.thread.impl3.SingleThread.run(SingleThread.java:162)
Caused by: com.sap.engine.services.applocking.exception.SAPAppLockingIllegalArgumentException: Inconsistency in number of primary keys
at com.sap.engine.services.applocking.TableLockingImpl.getArgument(TableLockingImpl.java:385)
at com.sap.engine.services.applocking.TableLockingImpl.lock(TableLockingImpl.java:128)
at com.sap.engine.services.applocking.TableLockingImpl.lock(TableLockingImpl.java:138)
at com.sap.engine.services.ejb.entity.pm.lock.TableLockingSystem.write(TableLockingSystem.java:82)
at com.sap.engine.services.ejb.entity.pm.PersistentM2M.create(PersistentM2M.java:172)
at com.sap.engine.services.ejb.entity.pm.PersistentCacheM2M.add(PersistentCacheM2M.java:197)
at com.sap.engine.services.ejb.entity.pm.multiple.CollectionM2M.add(CollectionM2M.java:57)
at com.atosorigin.tcc.testing.ejbses.profiling.ProfilerBean.assignSolution(ProfilerBean.java:201)
at com.atosorigin.tcc.testing.ejbses.profiling.ProfilerObjectImpl0.assignSolution(ProfilerObjectImpl0.java:771)
... 32 more
I can't figure out what the problem is with the ORM mapping defined.
On the database level I have three tables. Consultant maps to PFL_CONSULTANT, Solution to PFL_SAPSOLUTIONS. The third table PFL_CONS_SOL_MAP is the help table used for the relationship (having two fields, which are in fact foreign keys from the other two tables to express the assignment of solutions to consultants (where a consultant can have one or more solutions).
ps. : I am running Netweaver Developer Workplace (Netweaver 2004, at stack level 5)
Message was edited by: Theo PaesenHm, after disabling 'automatic locking' it works.
-
[ADF] Adding/deleting entries in a many-to-many relationship
I am using JDeveloper 10.1.3 and the ADF BC / ADF Model / ADF Faces / JSF technology stack.
For this question, I am using the SRDemo application as an example, specifically the many-to-many relationship between USERS and PRODUCTS (the Staff Expertise relationship), outlined in red in this schema diagram: Image Link
Users may have any number of product expertise areas and many users may have the same product expertise area. For the purposes of this example I have added two reference fields from the PRODUCT table into the ExpertiseAreas VO (Name and Description), outlined in red in this data control palette section: Image Link
I have created a page which shows the details of a user (1), along with a table showing the expertise areas the user has (3), and a table of all the products available (2), numbered on this design page: Image Link and corresponding to the numbered data controls on this data control palette section: Image Link, where 1 is rendered as an ADF Read-only Form, 2 is an ADF Read-only Table with a tableSelectMany element in the selection facet, and 3 is also an ADF Read-only Table.
What I am trying to do is have the tableSelectMany element reflect which of the products are linked to the current user in the expertise areas relationship (by having the checkbox for currently linked products checked), and when you check or uncheck a product's checkbox, it should add or remove the row in the EXPERTISE_AREAS intersection table, respectively (asume for this example that there are default values for Expertise Level and Notes).
So far I have been following the process used in section 19.8 of the ADF Developer's Guide for Forms/4GL Developers, which describes how to set up a selectManyShuttle which implements the adding and deleting functionality. So I have a Client Interface method in the Application Module, updateSkillsForCurrentStaff (described in section 10.6.7.2), and I have a selection listener for the assignment table in the backing bean for the page, which calls the updateSkillsForCurrentStaff method:
public void selectionChanged(SelectionEvent event)
BindingContainer bc = getBindings();
DCIteratorBinding productsIB = (DCIteratorBinding)bc.get("ProductListIterator");
Set keys = getTable1().getSelectionState().getKeySet();
Iterator iter = keys.iterator();
List productIds = new Vector();
while (iter.hasNext())
String product = ((Key)iter.next()).toStringFormat(true);
productsIB.setCurrentRowWithKey(product);
ViewRowImpl productRow = (ViewRowImpl)productsIB.getCurrentRow();
Number productId = (Number)productRow.getAttribute("Id");
productIds.add(productId);
OperationBinding ob = bc.getOperationBinding("updateSkillsForCurrentStaff");
Map pm = ob.getParamsMap();
pm.put("productIds", productIds);
ob.execute();
All of this works, but I can't work out how to link the selection state of the assignment table to the expertise areas that are linked to the user. Also I think the method listing above must be a bit of a hack, but I don't know enough about this to know if there's an easier way of doing it.
Any help is appreciated.Have a look at this example I cooked up for you.
http://radio.weblogs.com/0118231/2006/10/03.html#a739
It might not be the first way one thinks to implement something, but it illustrates a very interesting, model-centric approach to the problem you propose.
My feelings won't be hurt if you prefer a more view-centric approach, but I wanted to illustrate what was a maximally-model-centric solution (in fact, which doesn't even require a backing bean!) If you like a more view-centric approach, I can help you figure out what's wrong with your key-handling above. For one, I would probably start by passing the Set of Key's directly to the middle tier application module method to eliminate client-side code.
Check it out and let me know what you think. Try it directly in the Business Components Tester to appreciate one of the benefits a model-centric solution can bring. -
Working with many-to-many relationships
I am about to start my first experience with many-to-many
relationships using PHP and MySQL.
My project is to create an events registration form. As you
know, there can be many events and many participants attending many
events.
I am not sure on how to structure my database and tables so I
will first show you what I have:
create table programs (
program_id int not null primary key auto_increment,
program_name varchar(100) not null,
program_date varchar(25) not null,
program_time varchar(25) not null,
program_coordinator varchar(100),
program_seats int not null
create table participants (
participant_id int not null primary key auto_increment,
participant_name varchar(100) not null,
participant_phone varchar(12) not null
I know that I need a middle table to join the two.
create table programs_participants (
program_id int references program(id),
participants_id int references participants(id),
primary key (program_id, participants_id)
My problem is, how do I submit to both the participants AND
the programs_participants table together? Or is this not possible?
The participants are not already in the database when we register
them. We enter their personal info and select their desired events
from checkboxes on the same page.
Thanks for your help.> My problem is, how do I submit to both the participants
AND the
> programs_participants table together? Or is this not
possible? The
> participants are not already in the database when we
register them. We
> enter
> their personal info and select their desired events from
checkboxes on the
> same
> page.
What you need to do is a multi-step insert.
First, you insert the new participant into the participant
table, then use
the @@identity command to get the uniqueID of that newly
entered record.
Then you can take that uniqueID to build the entry for the
programs_participants table.
If you use a stored procedure, you should be able to do all
of that with
only having to create one call to the DB from your
Application.
_Darrel
Maybe you are looking for
-
Field in the dropdown in PCR.
Hi, We have custom infotype 9500 and bonus types are maintained in custom infotype. there are 6 entries in the bonus types dropdown and one field in the dropdown xxxxx we are not using from 2008. We dont want that field to fetch to the portal in the
-
Letterbox downloads and installs and is enabled, but does not produce the 3 columns in the mail window. I had the same problem with 10.6.7 and now 10.6.8. The download is the latest version (0.24b9) and the forums indicated that it works with both
-
Check for Correct File Name Syntax
What is the most efficient way to check if a String can be used as a file name? Here is my current (bulky) way: public static boolean isValidFileName(String s) { try { File file = new File(s); file.mkdir(); file.del
-
Convert Array to Proper English?
Here's my problem: I have a bunch of arrays ranging from 2 to 8 members. They look, of course, like this: "red,green,blue" but I need to wind up with a string of : "red, green, and blue" with a space after each comma and an "and" before the last memb
-
Firefox initially opens new tabs as tabs, then switches to new windows
I am running FF 14.0.1 and the following problem has persisted through a number of versions. Initially FF will open new tabs...Ctrl+t works, right-click open in new tab etc. all work fine. Sometimes tabs are now issue and I can have maybe 20 or more