The Source for Java Technology Collaboration
Webmaster Alert: Posting to Jive Forums is currently not working. Estimated time for fix is unknown.

Home » java.net Forums » GlassFish » GlassFish

Thread: Problem with @ManyToOne mapping

Welcome, Guest Help
Login Login
Guest Settings Guest Settings
Reply to this Thread Reply to this Thread Search Forum Search Forum Back to Thread List Back to Thread List

Permlink Replies: 3 - Last Post: Jan 23, 2006 8:13 AM by: dibyendumajumdar
dibyendumajumdar

Posts: 55
Problem with @ManyToOne mapping
Posted: Jan 16, 2006 7:44 AM
  Click to reply to this thread Reply

Hi,

I am using the TPC-C benchmark schema definition for my experiments with EJB 3.0. I am trying to map the Warehouse and District tables. The Warehouse table has a single ID column as primary key, but the district table has a composite primary key that consists of an ID column and a warehouse ID column. Reproduced below is part of the SQL script to create the tables:

CREATE TABLE TPCC.WAREHOUSE (
W_ID INTEGER NOT NULL GENERATED ALWAYS AS IDENTITY (START WITH 1 ,INCREMENT BY 1),
CONSTRAINT PK_WAREHOUSE PRIMARY KEY(W_ID),
);
CREATE TABLE TPCC.DISTRICT (
D_ID INTEGER NOT NULL,
D_W_ID INTEGER NOT NULL,
CONSTRAINT PK_DISTRICT PRIMARY KEY(D_W_ID, D_ID),
CONSTRAINT FK_WAREHOUSE FOREIGN KEY(D_W_ID) REFERENCES TPCC.WAREHOUSE ( W_ID )
ON UPDATE RESTRICT ON DELETE RESTRICT
);

I have mapped these as follows (again an excerpt):

@Entity
@Table(name="WAREHOUSE", schema="TPCC")
public class Warehouse {

Long id;

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="W_ID")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}

@Entity
@Table(name = "DISTRICT", schema = "TPCC")
@IdClass(schema1.entity.tpcc.District.DistrictPK.class)
public class District {

Warehouse warehouse;

Long id;

Long warehouseId;

@Id
@Column(name = "D_ID", nullable=false)
@GeneratedValue(strategy = GenerationType.TABLE, generator = "DISTRICT_ID_SEQUENCE")
@TableGenerator(name = "DISTRICT_ID_SEQUENCE", table = "IDGENERATOR", schema = "TPCC", pkColumnName = "SEQ_NAME", valueColumnName = "SEQ_COUNT", pkColumnValue = "DISTRICT_ID_SEQUENCE", allocationSize = 10)
public Long getId() {
return id;
}

@Id
@Column(name = "D_W_ID", nullable=false)
public Long getWarehouseId() {
return warehouseId;
}

@ManyToOne
@JoinColumn(name = "D_W_ID", referencedColumnName = "W_ID")
public Warehouse getWarehouse() {
return warehouse;
}

public void setWarehouseId(Long warehouseId) {
this.warehouseId = warehouseId;
}

public void setId(Long id) {
this.id = id;
}

public void setWarehouse(Warehouse warehouse) {
this.warehouse = warehouse;
this.warehouseId = warehouse.getId();
}

public static class DistrictPK {
Long id;

Long warehouseId;

public Long getId() {
return id;
}

public Long getWarehouseId() {
return warehouseId;
}

public void setId(Long id) {
this.id = id;
}

public void setWarehouseId(Long warehouseId) {
this.warehouseId = warehouseId;
}

@Override
public boolean equals(Object arg0) {
if (arg0 == this) {
return true;
} else if (arg0 instanceof DistrictPK) {
DistrictPK other = (DistrictPK) arg0;
return id.equals(other.id)
&& warehouseId.equals(other.warehouseId);
}
return false;
}

@Override
public int hashCode() {
return id.hashCode() ^ warehouseId.hashCode();
}
}
}

When I try to run a program, I am getting the following exception:

Exception [TOPLINK-48] (Oracle TopLink Essentials - 10g release 4 (10.1.4.0.0) (Build 060104Dev)): oracle.toplink.essentials.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [TPCC.DISTRICT.D_W_ID]. Only one may be defined as writable, all others must be specified read-only.
Mapping: oracle.toplink.essentials.mappings.OneToOneMapping[warehouse]
Descriptor: RelationalDescriptor(schema1.entity.tpcc.District --> [DatabaseTable(TPCC.DISTRICT)])

Runtime Exceptions:
---------------------------------------------------------

at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:428)
at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:360)
at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:677)
at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.login(DatabaseSessionImpl.java:572)
at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:160)
at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createEntityManagerFactory(EntityManagerFactoryProvider.java:100)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:59)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
at schema1.cmdline.InsertWarehouse.main(InsertWarehouse.java:20)

Descriptor Exceptions:
---------------------------------------------------------


Local Exception Stack:
Exception [TOPLINK-48] (Oracle TopLink Essentials - 10g release 4 (10.1.4.0.0) (Build 060104Dev)): oracle.toplink.essentials.exceptions.DescriptorException
Exception Description: Multiple writable mappings exist for the field [TPCC.DISTRICT.D_W_ID]. Only one may be defined as writable, all others must be specified read-only.
Mapping: oracle.toplink.essentials.mappings.OneToOneMapping[warehouse]
Descriptor: RelationalDescriptor(schema1.entity.tpcc.District --> [DatabaseTable(TPCC.DISTRICT)])
at oracle.toplink.essentials.exceptions.DescriptorException.multipleWriteMappingsForField(DescriptorException.java:919)
at oracle.toplink.essentials.internal.descriptors.ObjectBuilder.initialize(ObjectBuilder.java:1817)
at oracle.toplink.essentials.descriptors.ClassDescriptor.initialize(ClassDescriptor.java:1786)
at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:399)
at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.initializeDescriptors(DatabaseSessionImpl.java:360)
at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.postConnectDatasource(DatabaseSessionImpl.java:677)
at oracle.toplink.essentials.internal.sessions.DatabaseSessionImpl.login(DatabaseSessionImpl.java:572)
at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.login(EntityManagerFactoryProvider.java:160)
at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createEntityManagerFactory(EntityManagerFactoryProvider.java:100)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:59)
at javax.persistence.Persistence.createEntityManagerFactory(Persistence.java:48)
at schema1.cmdline.InsertWarehouse.main(InsertWarehouse.java:20)

Any idea what this means?

Regards

Dibyendu

dibyendumajumdar

Posts: 55
Re: Problem with @ManyToOne mapping
Posted: Jan 17, 2006 8:14 AM   in response to: dibyendumajumdar
  Click to reply to this thread Reply

I reported this problem to the EJB spec people, and thanks to a reply from Mike Keith, the problem is resolved. I quote his reply here:

QUOTE
Although you have correctly mapped the warehouseId and the warehouse fields to the same column you need to make one of them read-only. Try mapping the warehouseId the following way:

@Id @Column(name="D_W_ID", nullable=false, insertable=false, updatable=false)
public Long getWarehouseId() { return warehouseId; }
ENDQUOTE

I made this change and it resolved the problem.

ss141213

Posts: 500
Re: Problem with @ManyToOne mapping
Posted: Jan 17, 2006 7:17 PM   in response to: dibyendumajumdar
  Click to reply to this thread Reply

Have a look at https://glassfish.dev.java.net/issues/show_bug.cgi?id=163
where this issue is being discussed at length.

-- Sahoo

dibyendumajumdar

Posts: 55
Re: Problem with @ManyToOne mapping
Posted: Jan 23, 2006 8:13 AM   in response to: ss141213
  Click to reply to this thread Reply

Here is my attempt to explain the issue with mapping relationships between entities that have composite keys:

http://trycatchfinally.blogspot.com/2006/01/mapping-relationships-in-ejb-30.html

I would appreciate feedback - does the explanation make sense?

Thanks




 XML java.net RSS