|
Replies:
4
-
Last Post:
Jul 2, 2006 7:37 PM
by: swapnali
|
|
|
|
|
|
|
Please help..Problem in persitence, data not added in db
Posted:
Jun 30, 2006 12:20 AM
|
|
|
I have a account and address entity beans. One account can have multiple addresses. I was testing my application , and was getting some results too. but when I checked my database I found that in the address table, mapping field (to account id) is NULL!!!!! and still my ejbs are showing proper data. Please see the code and tables below. Please let tme know if I am doing something wrong. I am stuck for many days here :(
Table Create table ACC_ADDRESS ( address_id INTEGER PRIMARY KEY, address1 varchar(50), address2 varchar(50), streetname varchar(30), cityname varchar(20), statename varchar(20), country varchar(20), pin varchar(10), mappedaccid INTEGER
);
Create table ACCOUNT ( accid INTEGER PRIMARY KEY, firstname varchar(30), lastname varchar(30), dob TIMESTAMP
);
ALTER TABLE ACC_ADDRESS ADD CONSTRAINT ACC_ADDR FOREIGN KEY (mappedaccid) REFERENCES ACCOUNT (accid);
Account bean package com.ing.demo.account;
import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Collection; import java.util.Date;
import javax.persistence.CascadeType; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.OneToMany; import javax.persistence.Table; import javax.persistence.Temporal; import javax.persistence.TemporalType;
@Entity @Table(name ="ACCOUNT") @NamedQueries ({ @NamedQuery(name = "findAllAccounts", query = "SELECT OBJECT(a) FROM Account a"), @NamedQuery(name = "findAllAccountId", query = "SELECT distinct a.accid FROM Account a") })
public class Account implements java.io.Serializable {
@Id @GeneratedValue(strategy = GenerationType.AUTO) private int accid;
private String firstName;
private String lastName;
@Temporal(TemporalType.DATE) private Date dob;
@OneToMany(mappedBy="account",cascade=CascadeType.ALL,fetch=FetchType.LAZY) private Collection<Address> addresses;
public Account() { } public Account (String firstName, String lastName, Date dob) { this.firstName = firstName; this.lastName = lastName; this.dob =dob; this.addresses = new ArrayList<Address>(); }
//@OneToMany(mappedBy="account",cascade=CascadeType.ALL,fetch=FetchType.LAZY) public Collection<Address> getAddresses() { return addresses; }
public void setAddresses(Collection <Address> addresses) { System.out.println("Setting addresses"); this.addresses = addresses; } public void setAddress(Address address) { System.out.println("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@"+getAddresses()); getAddresses().add(address);
} @Temporal(TemporalType.DATE) public Date getDob() { return dob; }
public void setDob(Date dob) { this.dob = dob; }
public String getFirstName() { return firstName; }
public void setFirstName(String firstName) { this.firstName = firstName; }
@Id //@GeneratedValue(strategy = GenerationType.AUTO) public int getAccid() { return accid; } public void setAccid(int id) { this.accid = id; }
public String getLastName() { return lastName; }
public void setLastName(String lastName) { this.lastName = lastName; }
}
Address bean
package com.ing.demo.account;
import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.FetchType; import javax.persistence.GeneratedValue; import javax.persistence.GenerationType; import javax.persistence.Id; import javax.persistence.JoinColumn; import javax.persistence.ManyToOne; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import javax.persistence.Table;
@Entity @Table (name = "ACC_ADDRESS") //@NamedQueries{ @NamedQuery(name="findAddressesForAccount", query="SELECT a from Address a where a.accId = :id") //}
//@NamedQuery(name="findAddresses",query="SELECT a from Address a ") public class Address implements java.io.Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name="address_id") private int Id; private String address1; private String address2; private String streetName; private String cityName; private String stateName; private String country; private String pin;
//private int mappedaccid; @ManyToOne(fetch=FetchType.LAZY) @JoinColumn(name="mappedaccid", referencedColumnName="accid") private Account account; public Address() { } public Address( String address1, String address2,String streetName, String cityName, String stateName, String country, String pin) { this.address1 = address1; this.address2 = address2; this.streetName = streetName; this.stateName = stateName; this.cityName = cityName; this.country = country; this.pin = pin; this.account = null; } //@ManyToOne(fetch=FetchType.LAZY) //@JoinColumn(name="mappedaccid", referencedColumnName="accid") public Account getAccount() { return this.account; }
public void setAccount(Account account) { this.account = account; } public String getAddress1() { return address1; }
public void setAddress1(String address1) { this.address1 = address1; }
public String getAddress2() { return address2; }
public void setAddress2(String address2) { this.address2 = address2; }
public String getCityName() { return cityName; }
public void setCityName(String cityName) { this.cityName = cityName; }
public String getCountry() { return country; }
public void setCountry(String country) { this.country = country; }
public String getPin() { return pin; }
public void setPin(String pin) { this.pin = pin; }
public String getStateName() { return stateName; }
public void setStateName(String stateName) { this.stateName = stateName; }
public String getStreetName() { return streetName; }
public void setStreetName(String streetName) { this.streetName = streetName; }
@Id public int getId() { return Id; } public void setId(int id) { this.Id = id; }
}
Method of Stateless bean to create the data
public void createData(String fName, String lName, String dt, String address1,String address2,String streetName, String cityName, String stateName, String country, String pin) { Hashtable data = new Hashtable(); data.put("FIRST_NAME",fName); data.put("LAST_NAME",lName); DateFormat myDateFormat = new SimpleDateFormat("MM/dd/yyyy"); Date d = null; try { d = myDateFormat.parse(dt); } catch (ParseException e) { // TODO Auto-generated catch block e.printStackTrace(); } data.put("DOB",d); data.put("ADDRESS1",address1); data.put("ADDRESS2",address2); data.put("STREET_NAME",streetName); data.put("CITY_NAME",cityName); data.put("STATE_NAME",stateName); data.put("COUNTRY",country); data.put("PIN",pin); createCompleteAccount(data); } public void createCompleteAccount(Hashtable accData) {
Account acc = new Account((String)accData.get("FIRST_NAME"),(String)accData.get("LAST_NAME"),(Date)accData.get("DOB")); em.persist(acc);
Address addr = new Address((String)accData.get("ADDRESS1"),(String)accData.get("ADDRESS2"),(String)accData.get("STREET_NAME"),(String)accData.get("CITY_NAME"), (String)accData.get("STATE_NAME"),(String)accData.get("COUNTRY"),(String)accData.get("PIN")); //em.persist(addr); System.out.println("******************ACC ID********************************* "+acc.getAccid()+" *************"); acc.setAddress(addr); //em.persist(acc); }
|
|
|
|
|
|
|
Re: Please help..Problem in persitence, data not added in db
Posted:
Jun 30, 2006 12:43 AM
in response to: swapnali
|
|
|
Hi,
Your entities show the data, because all the data is cached at an EMF level as-is (i.e. as you have it at the end of the transaction). To make sure that the relationships are flushed to the database, you need to set them up from the owning side (Address in your case). Even better would be to to set the relationship from both sides to make sure that your in memory representation is correct (remember that it's cached as-is and is not managed for you by the persistence provider).
Regards, -marina
|
|
|
|
|
|
|
|
Re: Please help..Problem in persitence, data not added in db
Posted:
Jun 30, 2006 1:14 AM
in response to: mvatkina
|
|
|
Marina, Thanks for response. I added a call addr.setAccount(acc) in the stateless bean, before setting address.
but it gave me error as below [#|2006-06-30T17:11:39.274+0900|SEVERE|sun-appserver-pe9.0|javax.enterprise.system.container.ejb|_ThreadID=11;_ThreadName=httpWorkerThread-9090-0;_RequestID=09e28713-887b-409b-a04b-8e88b5f73a16;|EJB5071: Some remote or transactional roll back exception occurred Local Exception Stack: Exception [TOPLINK-45] (Oracle TopLink Essentials - 2006.4 (Build 060412)): oracle.toplink.essentials.exceptions.DescriptorException Exception Description: Missing mapping for field [ACCOUNT.accid]. Descriptor: RelationalDescriptor(com.ing.demo.account.Account --> [DatabaseTable(ACCOUNT)]) at oracle.toplink.essentials.exceptions.DescriptorException.missingMappingForField(DescriptorException.java:885) at oracle.toplink.essentials.internal.descriptors.ObjectBuilder.extractValueFromObjectForField(ObjectBuilder.java:1569) at oracle.toplink.essentials.mappings.OneToOneMapping.writeFromObjectIntoRow(OneToOneMapping.java:1117) at oracle.toplink.essentials.internal.descriptors.ObjectBuilder.buildRow(ObjectBuilder.java:723) at oracle.toplink.essentials.internal.descriptors.ObjectBuilder.buildRow(ObjectBuilder.java:711) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWrite(DatabaseQueryMechanism.java:425) at oracle.toplink.essentials.queryframework.InsertObjectQuery.executeCommit(InsertObjectQuery.java:74) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedWrite(DatabaseQueryMechanism.java:635) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.performUserDefinedInsert(DatabaseQueryMechanism.java:599) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.insertObjectForWriteWithChangeSet(DatabaseQueryMechanism.java:495) at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeCommitWithChangeSet(WriteObjectQuery.java:130) at oracle.toplink.essentials.internal.queryframework.DatabaseQueryMechanism.executeWriteWithChangeSet(DatabaseQueryMechanism.java:283) at oracle.toplink.essentials.queryframework.WriteObjectQuery.executeDatabaseQuery(WriteObjectQuery.java:67) at oracle.toplink.essentials.queryframework.DatabaseQuery.execute(DatabaseQuery.java:609) at oracle.toplink.essentials.queryframework.DatabaseQuery.executeInUnitOfWork(DatabaseQuery.java:536) at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWorkObjectLevelModifyQuery(ObjectLevelModifyQuery.java:123) at oracle.toplink.essentials.queryframework.ObjectLevelModifyQuery.executeInUnitOfWork(ObjectLevelModifyQuery.java:95) at oracle.toplink.essentials.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2211) at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:937) at oracle.toplink.essentials.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:894) at oracle.toplink.essentials.internal.sessions.CommitManager.commitNewObjectsForClassWithChangeSet(CommitManager.java:254) at oracle.toplink.essentials.internal.sessions.CommitManager.commitAllObjectsForClassWithChangeSet(CommitManager.java:231) at oracle.toplink.essentials.internal.sessions.CommitManager.commitAllObjectsWithChangeSet(CommitManager.java:187) at oracle.toplink.essentials.internal.sessions.AbstractSession.writeAllObjectsWithChangeSet(AbstractSession.java:2643)
|
|
|
|
|
|
|
|
Re: Please help..Problem in persitence, data not added in db
Posted:
Jun 30, 2006 9:40 AM
in response to: swapnali
|
|
|
Hello,
Not sure what is going on, but you may want to try removing the referencedColumnName="accid" from the JoinColumn annotation to see if letting it default works.
Also noticed your query for Address is:
@NamedQuery(name="findAddressesForAccount", query="SELECT a from Address a where a.accId = :id")
Address though doesn't have an accId attribute. Also, you still have annotations on both fields and methods. Looks like the annotations on the fields should work, so you may want to remove all annotations on the methods to be sure they aren't contributing to the issue.
Best Regards, Chris
|
|
|
|
|
|
|
|
Re: Please help..Problem in persitence, data not added in db
Posted:
Jul 2, 2006 7:37 PM
in response to: chris_delahunt
|
|
|
Hi Chris, Thanks for your response. I have done changes suggested by you, and some more changes. Now after create, I can see the mapped id in database address table. BUT now the function getAllAccount() or getAccount(int) is not working. The system.out added in the service class, prints the data properly but, does not return it 
It is giving the exception shown below.
for getAcount(int) method call
[#|2006-07-03T11:22:44.667+0900|WARNING|sun-appserver-pe9.0|javax.enterprise.system.container.ejb|_ThreadID=15;_ThreadName=httpWorkerThread-9090-1;_RequestID=0180c700-936f-4cab-b1fd-dceefbe00253;|invocation error on ejb endpoint AccountDemoService at /AccountDemoServiceService/AccountDemoService : null java.lang.StackOverflowError at java.lang.String.valueOf(String.java:2682) at com.sun.xml.bind.DatatypeConverterImpl._printInt(DatatypeConverterImpl.java:436) at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$17.print(RuntimeBuiltinLeafInfoImpl.java:628) at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$17.print(RuntimeBuiltinLeafInfoImpl.java:627) at com.sun.xml.bind.v2.model.impl.RuntimeBuiltinLeafInfoImpl$StringImpl.writeText(RuntimeBuiltinLeafInfoImpl.java:117) at com.sun.xml.bind.v2.runtime.LeafBeanInfoImpl.serializeBody(LeafBeanInfoImpl.java:89) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:594) at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:114) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:293) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:594) at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:114) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:293) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:594) at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:29)
for getAllAccounts() method call
[#|2006-07-03T11:32:05.280+0900|WARNING|sun-appserver-pe9.0|javax.enterprise.system.container.ejb|_ThreadID=15;_ThreadName=httpWorkerThread-9090-1;_RequestID=0180c700-936f-4cab-b1fd-dceefbe00253;|invocation error on ejb endpoint AccountDemoService at /AccountDemoServiceService/AccountDemoService : null java.lang.StackOverflowError at sun.reflect.GeneratedMethodAccessor186.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) at java.lang.reflect.Method.invoke(Method.java:585) at com.sun.xml.bind.v2.runtime.reflect.Accessor$GetterSetterReflection.get(Accessor.java:271) at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:90) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:293) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:594) at com.sun.xml.bind.v2.runtime.property.SingleElementNodeProperty.serializeBody(SingleElementNodeProperty.java:114) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:293) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:594) at com.sun.xml.bind.v2.runtime.property.ArrayElementNodeProperty.serializeItem(ArrayElementNodeProperty.java:29) at com.sun.xml.bind.v2.runtime.property.ArrayElementProperty.serializeListBody(ArrayElementProperty.java:132) at com.sun.xml.bind.v2.runtime.property.ArrayERProperty.serializeBody(ArrayERProperty.java:101) at com.sun.xml.bind.v2.runtime.ClassBeanInfoImpl.serializeBody(ClassBeanInfoImpl.java:293) at com.sun.xml.bind.v2.runtime.XMLSerializer.childAsXsiType(XMLSerializer.java:594)
=================================
changes which I did in code are as below
1. discarded the changes done in my earlier post. 2. removed all method annotations. 3. Rectified the query for getting address. 4. In stateless bean changed the create method as below public void createCompleteAccount(Hashtable accData) {
Account acc = new Account((String)accData.get("FIRST_NAME"),(String)accData.get("LAST_NAME"),(Date)accData.get("DOB")); em.persist(acc);
Address addr = new Address((String)accData.get("ADDRESS1"),(String)accData.get("ADDRESS2"),(String)accData.get("STREET_NAME"),(String)accData.get("CITY_NAME"), (String)accData.get("STATE_NAME"),(String)accData.get("COUNTRY"),(String)accData.get("PIN")); em.persist(addr); acc.setAddress(addr); }
5. and in Account entity bean changed the following method
public void setAddress(Address address) { address.setAccount(this); getAddresses().add(address);
}
|
|
|
|
|