@Embeddable class

Hello everyone,

I have 3 entity classes:

@Entity

@Table(name="CUSTOMER")

publicclass Customerentimplements Serializable{

........................

.........................}

@Entity

@Table(name="ITEMS")

..................

publicclass Iteamdetailsentimplements Serializable{

.............................

.............................

.............................}

@Entity

@Table(name="COLLECTPOINTORDERS")

publicclass CollOrdersrementimplements java.io.Serializable{

......................................................}

-

I have trying to make all these classed into composite keys, so I created an embeddable class as follows:

package StockInformation;

import java.util.Collection;

import java.util.List;

import javax.ejb.*;

import javax.persistence.Column;

import javax.persistence.Embeddable;

import javax.persistence.Entity;

import javax.persistence.Id;

import javax.persistence.JoinColumn;

import javax.persistence.ManyToMany;

import javax.persistence.ManyToOne;

import javax.persistence.OneToMany;

import javax.persistence.Table;

@Embeddable

@Table(name="COLLPOINTORDERLINE")

publicclass CollOrdlinementPKimplements java.io.Serializable{

@JoinColumn(name="itmid")

private Iteamdetailsent iteamdetailsent;

@JoinColumn(name="cusid")

@ManyToOne

private Customerent customerent;

@JoinColumn(name="collOrdID")

@ManyToOne

private CollOrdersrement collOrdersrement;

}

I get the following errors:

[#|2007-06-14T10:02:14.312+0100|SEVERE|sun-appserver-pe9.0|javax.enterprise.system.tools.deployment|_ThreadID=16;_ThreadName=Thread-36;_RequestID=14698a97-5f07-4767-89d2-9d7c3a0538b7;|Exception occured in J2EEC Phase

com.sun.enterprise.deployment.backend.IASDeploymentException

at java.util.AbstractList$Itr.next(AbstractList.java:427)

at oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataDescriptor.getPrimaryKeyFieldName(MetadataDescriptor.java:494)

at oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.ObjectAccessor.processOneToOneForeignKeyRelationship(ObjectAccessor.java:107)

at oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.ObjectAccessor.processOwningMappingKeys(ObjectAccessor.java:92)

at oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.ManyToOneAccessor.process(ManyToOneAccessor.java:73)

at oracle.toplink.essentials.internal.ejb.cmp3.metadata.accessors.RelationshipAccessor.processRelationship(RelationshipAccessor.java:250)

at oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProject.processRelationshipDescriptors(MetadataProject.java:513)

at oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProject.process(MetadataProject.java:445)

at oracle.toplink.essentials.internal.ejb.cmp3.metadata.MetadataProcessor.processAnnotations(MetadataProcessor.java:203)

at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.processORMetadata(EntityManagerSetupImpl.java:993)

at oracle.toplink.essentials.internal.ejb.cmp3.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:501)

at oracle.toplink.essentials.ejb.cmp3.EntityManagerFactoryProvider.createContainerEntityManagerFactory(EntityManagerFactoryProvider.java:152)

at com.sun.jdo.spi.persistence.support.ejb.ejbc.PersistenceProcessor.loadPersistenceUnitBundle(PersistenceProcessor.java:467)

at com.sun.jdo.spi.persistence.support.ejb.ejbc.PersistenceProcessor.createTablesInDB(PersistenceProcessor.java:325)

at com.sun.jdo.spi.persistence.support.ejb.ejbc.PersistenceProcessor.processAppBundle(PersistenceProcessor.java:190)

at com.sun.jdo.spi.persistence.support.ejb.ejbc.PersistenceProcessor.processApplication(PersistenceProcessor.java:125)

at com.sun.jdo.spi.persistence.support.ejb.ejbc.DeploymentEventListenerImpl.processApplication(DeploymentEventListenerImpl.java:193)

at com.sun.jdo.spi.persistence.support.ejb.ejbc.DeploymentEventListenerImpl.processEvent(DeploymentEventListenerImpl.java:152)

at com.sun.jdo.spi.persistence.support.ejb.ejbc.DeploymentEventListenerImpl.notifyDeploymentEvent(DeploymentEventListenerImpl.java:109)

at com.sun.enterprise.deployment.backend.DeploymentEventManager.notifyDeploymentEvent(DeploymentEventManager.java:66)

at com.sun.enterprise.deployment.backend.AppDeployer.postDeploy(AppDeployer.java:429)

at com.sun.enterprise.deployment.backend.AppDeployer.deploy(AppDeployer.java:225)

at com.sun.enterprise.deployment.backend.AppDeployer.doRequestFinish(AppDeployer.java:129)

at com.sun.enterprise.deployment.phasing.J2EECPhase.runPhase(J2EECPhase.java:169)

at com.sun.enterprise.deployment.phasing.DeploymentPhase.executePhase(DeploymentPhase.java:95)

at com.sun.enterprise.deployment.phasing.PEDeploymentService.executePhases(PEDeploymentService.java:871)

at com.sun.enterprise.deployment.phasing.PEDeploymentService.deploy(PEDeploymentService.java:266)

at com.sun.enterprise.deployment.phasing.PEDeploymentService.deploy(PEDeploymentService.java:739)

at com.sun.enterprise.management.deploy.DeployThread.deploy(DeployThread.java:174)

at com.sun.enterprise.management.deploy.DeployThread.run(DeployThread.java:210)

|#]

Bearing in mind this is my first time of Embeddable class, what am I doing wrong?

Thanks

eve

[6509 byte] By [evepokuaa] at [2007-11-27 7:39:33]
# 1

Hi Eve,

I'm not sure what you want to accomplish. All fields of embeddable classes will be mapped to the database table of the embedding entity, so you shouldn't specify an @Table annotation. Also, only Basic, Column, Lob, Temporal, and Enumerated mapping annotations may portably be used in the embeddable class. Please see the JPA spec, in particular section 9.1.34: Embeddable Annotation.

mf125085a at 2007-7-12 19:20:13 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 2

Hello,

This problem has been resolved and I used IdClass. I had three enitities

and and extra entity which contains composite keys of the other entity classes to resolve the manytomany issue. Thanks

A code of the Id class and the class containing the composite key is as follows:

IdClass:

public class CollOrdlinementKey implements java.io.Serializable{

private String itmid;

private String cusid;

private String collOrdID;

public CollOrdlinementKey(){}

public CollOrdlinementKey(String itmid, String cusid){

this.setitmid(itmid);

this.setcusid(cusid);

}

public int hashCode() {

return (((this.getcollOrdID() == null) ? 0 : this.getcollOrdID()

.hashCode()));

//((String) this.getitmid()));

}

public boolean equals(Object otherOb) {

if (this == otherOb) {

return true;

}

if (!(otherOb instanceof CollOrdlinementKey)) {

return false;

}

CollOrdlinementKey other = (CollOrdlinementKey) otherOb;

return (((this.getitmid() == null) ? (other.getitmid() == null)

: this.getitmid()

.equals(other.getitmid()))

&& (this.getitmid() == other.getitmid()));

}

public String toString() {

return "" + getitmid() + "-" + getcusid();

}

public String getitmid(){

return itmid;}

public void setitmid(String itmid){

this.itmid=itmid;}

public String getcusid()

{return cusid;}

public void setcusid(String cusid){

this.cusid=cusid;

}

public String getcollOrdID(){

return collOrdID;}

public void setcollOrdID(String collOrdID){

this.collOrdID=collOrdID;}

}

Composite key class:

@IdClass(StockInformation.CollOrdlinementKey.class)

@Entity

@Table(name="COLLPOINTORDERLINE")

public class CollOrdline implements java.io.Serializable{

private String itmid;

private String cusid;

private String collOrdID;

public CollOrdline(){}

@Id

public String getitmid(){

return itmid;}

public void setitmid(String itmid){

this.itmid=itmid;}

@Id

public String getcollOrdID(){

return collOrdID;}

public void setcollOrdID(String collOrdID){

this.collOrdID=collOrdID;}

@Id

public String getcusid()

{return cusid;}

public void setcusid(String cusid){

this.cusid=cusid;

}

}

Thanks

eve

evepokuaa at 2007-7-12 19:20:13 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 3

Hi Eve,

The methods equals and hashCode in CollOrdlinementKey *should* be based the same fields, i.e. itmid and cusid. This can be achieved by:

public int hashCode() {

if (this.getcusid() == null || this.getitmid() == null) {

return 0;

} else {

return (this.getcusid().hashCode() ^ this.getitmid().hashCode());

}

}

This way, you don't need the field

private String collOrdID;

in either CollOrdlineentKey and CollOrdlineent.

mf125085a at 2007-7-12 19:20:13 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 4

Hi,

Thank you for your help. I was a little confused with haseCodes();

I have now updated this method just like you mentioned. However, back to your suggestion:

This way, you don't need the field

private String collOrdID;

in either CollOrdlineentKey and CollOrdlineent.

I understand I may not need the

private String collOrdID;

in CollOrdlineentKey

but I do definately need it in:

public class CollOrdersrement implements java.io.Serializable{

.............}

as it is the primary key of this class:

@Entity

@Table(name="COLLECTPOINTORDERS")

public class CollOrdersrement implements java.io.Serializable{

@Id

@Column(name="CollORDID", nullable=false)

private String collOrdID;.........................

...........................}

And does how I understand it works within my composite key entity class:

@IdClass(StockInformation.CollOrdlinementKey.class)

@Entity

@Table(name="COLLPOINTORDERLINE")

public class CollOrdline implements java.io.Serializable{

private String itmid;

private String cusid;

private String collOrdID;

public CollOrdline(){}

@Id

public String getitmid(){

return itmid;}

public void setitmid(String itmid){

this.itmid=itmid;}

@Id

//@Column(name = "CollORDID", nullable = false, insertable = false, updatable = false)

public String getcollOrdID(){

return collOrdID;}

public void setcollOrdID(String collOrdID){

this.collOrdID=collOrdID;}

@Id

public String getcusid()

{return cusid;}

public void setcusid(String cusid){

this.cusid=cusid;

}

But I could be wrong. Please, explain if I'm wrong.

And what happens if my application deploys but this message:

'a non-getter method is annotated with a persistence annotation'

?

I am not sure where I'm going wrong. I would like to look into it even though the application deploys.

Thanks

eve

evepokuaa at 2007-7-12 19:20:13 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...
# 5
Hi Eve,There's no need for an extra collOrdId field. Every instance of CollOrdlineent connects exactly one Customerent to one Iteamdetailsent. This is why CollOrdlineent's primary key is defined by the combination of itmid and cusid.
mf125085a at 2007-7-12 19:20:13 > top of Java-index,Enterprise & Remote Computing,Enterprise Technologies...