-
1. Re: ManyToOne wont persist. help?
dhinojosa Aug 5, 2008 8:06 AM (in response to hcgpragt)Well, you don't have any @JoinColumn on the many to one relationships that's for sure. But that may not be your only problem. Serializable needs to have a capital S on your TelephoneNumber entity, and implements is misspelled on your TelephoneNumber entity too. Can you clean up your code, try it, and post again?
-
2. Re: ManyToOne wont persist. help?
hcgpragt Aug 6, 2008 4:49 PM (in response to hcgpragt)Hello, Im behind the devlopment machine now so I can cut and paste code instead of typing over.
Telephone Number:
package nl.unc.mmt.entity; import java.io.Serializable; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import nl.unc.mmt.util.TelephoneNumberType; import org.jboss.seam.annotations.Name; /** * Utility class for telephone numbers. * @author Hugo Pragt All rights reserverd * */ @Entity @Name("telephonenumber") @NamedQueries({ @NamedQuery(name="telephonenumber.findByNumber", query="select nr from TelephoneNumber nr where nr.number =:number") }) public class TelephoneNumber implements Serializable { private static final long serialVersionUID = -1134570748748658402L; private String cli; private String cps; private String countrycode; private String number; private TelephoneNumberType type = TelephoneNumberType.UNKNOWN; private Short category; /** * whether this telephone number is a national, international etc number. * defaults to UNKNOWN * @return the type of the number * @see TelephoneNumberType */ public TelephoneNumberType getType() { return type; } /** * @param type the type of the number * @see TelephoneNumberType */ public void setType(TelephoneNumberType type) { this.type = type; } /** * @return the category of the number */ public Short getCategory() { return category; } /** * @param category the category of the number to set */ public void setCategory(Short category) { this.category = category; } /** * @return all digits of telephone number */ @Id @Column(length=24) public String getCli() { return cli; } /** * @param digits id to set * @see #setCps(String) * @see #setCountrycode(String) * @see #setNumber(String) */ public void setCli(String digits) { cli = digits; } /** * @return the Carrier PreSelect code */ public String getCps() { return cps; } /** * @param cps the Carrier PreSelect code to set */ public void setCps(String cps) { this.cps = cps; } /** * @return the country code (without prefix zero's) */ public String getCountrycode() { return countrycode; } /** * @param countrycode the country code to set */ public void setCountrycode(String countrycode) { this.countrycode = countrycode; } /** * @return the number without CPS or country code */ public String getNumber() { return number; } /** * @param number the number without CPS or country code */ public void setNumber(String number) { this.number = number; } /** * outputs correctly formatted telephone number. * non-filled fields are ignored resulting in an ampty string for a * non-initialised telephone number. * @return CPS + CountryCode + Number */ @Override() public String toString() { StringBuffer result = new StringBuffer(); if (cps != null) { result.append(cps); } if (countrycode != null) { result.append("00"); result.append(countrycode); } if (number != null) { result.append(number); } return result.toString(); } /** * @see java.lang.Object#equals(java.lang.Object) */ @Override public boolean equals(Object obj) { if (obj == null) { return false; } if (! (obj instanceof TelephoneNumber)) { return false; } TelephoneNumber other = (TelephoneNumber)obj; if (cli == null) { return other.cli == null; } return cli.equals(other.cli); } /** * @see java.lang.Object#hashCode() */ @Override public int hashCode() { if (cli == null) { return 0; } return cli.hashCode(); } }
Call
I have removed some of the 80+ fields in this class
package nl.unc.mmt.entity; import java.io.Serializable; import java.util.Date; import java.util.HashSet; import java.util.Set; import javax.persistence.CascadeType; import javax.persistence.Column; import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.ManyToMany; import javax.persistence.ManyToOne; import javax.persistence.NamedNativeQueries; import javax.persistence.NamedNativeQuery; import javax.persistence.NamedQueries; import javax.persistence.NamedQuery; import nl.unc.mmt.util.LDCStatus; import nl.unc.mmt.util.ericsson.AxeCDR; import org.jboss.seam.annotations.Name; /** * A CDR read directly from data source by the CDR creator. * @author Hugo Pragt. All rights reserved * */ @Entity @Name("cdr") public class Cdr implements Serializable { private static final long serialVersionUID = 4003988589514561342L; private Long id; /** * true = this is a (fake) test CDR * default = false */ private boolean test = false; private TelephoneNumber anumber; private TelephoneNumber aNumber_UserPresented; private TelephoneNumber bnumber; private TelephoneNumber bNumber_AfterAnalyses; private TelephoneNumber xnumber; private Date start; private long duration; private boolean beingProcessed = false; @Id public Long getId() { return id; } public void setId(Long cdrId) { this.id = cdrId; } // http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html @Column(columnDefinition="tinyint", length=4) public boolean isTest() { return test; } public void setTest(boolean isTest) { this.test = isTest; } // http://java.sun.com/javaee/5/docs/api/javax/persistence/Column.html @Column(columnDefinition="tinyint", length=4) public boolean isRedirected() { return redirected; } // @ManyToOne(cascade={CascadeType.MERGE,CascadeType.PERSIST}) @ManyToOne public TelephoneNumber getAnumber() { return anumber; } public void setAnumber(TelephoneNumber number) { anumber = number; } // @ManyToOne(cascade={CascadeType.MERGE,CascadeType.PERSIST}) @ManyToOne public TelephoneNumber getANumber_UserPresented() { return aNumber_UserPresented; } public void setANumber_UserPresented(TelephoneNumber number) { aNumber_UserPresented = number; } // @ManyToOne(cascade={CascadeType.MERGE,CascadeType.PERSIST}) @ManyToOne public TelephoneNumber getBnumber() { return bnumber; } public void setBnumber(TelephoneNumber number) { bnumber = number; } // @ManyToOne(cascade={CascadeType.MERGE,CascadeType.PERSIST}) @ManyToOne public TelephoneNumber getBNumber_AfterAnalyses() { return bNumber_AfterAnalyses; } public void setBNumber_AfterAnalyses(TelephoneNumber number_AfterAnalyses) { bNumber_AfterAnalyses = number_AfterAnalyses; } // @ManyToOne(cascade={CascadeType.MERGE,CascadeType.PERSIST}) @ManyToOne public TelephoneNumber getXnumber() { return xnumber; } public void setXnumber(TelephoneNumber number) { xnumber = number; } public Date getStart() { return start; } public void setStart(Date start) { this.start = start; } /** * * @return chargeable duration in milliseconds */ public long getDuration() { return duration; } /** * * @param duration chargeable duration in milliseconds */ public void setDuration(long duration) { this.duration = duration; } @Override public String toString() { StringBuffer sb = new StringBuffer(Cdr.class.getSimpleName()); sb.append("(id="); sb.append(id); sb.append(",Anumber="); sb.append(anumber); sb.append(",Bnumber="); sb.append(bnumber); sb.append(",duration="); sb.append(duration); sb.append(')'); return sb.toString(); } /** * @return the beingProcessed */ @Column(columnDefinition="tinyint", length=4) public boolean isBeingProcessed() { return beingProcessed; } /** * @param beingProcessed the beingProcessed to set */ public void setBeingProcessed(boolean beingProcessed) { this.beingProcessed = beingProcessed; } }
call writing method
private CorruptedCdr handleRecord(String record) { String[] values = null; if (record != null) { values = record.split(","); } Cdr cdr = create(values); cdr.setTest(true); // TODO remove setTest(true) Cdr cdr2 = em.find(Cdr.class, cdr.getId()); if (cdr2 == null) { em.persist(cdr); // changed from merge to persist to avoid double PK's } else { log.warn("Overwriting {0}!", cdr2); em.merge(cdr); } log.debug("persisting new cdr {0}", cdr); } try { em.flush(); // TODO remove? } catch(PersistenceException e) { log.warn("while storing {0} in database: {1}", cdr, e); throw e; } return null;
Error log
2008-08-04 23:54:15,171 INFO [STDOUT] Hibernate: insert into TelephoneNumber (type, number, category, cps, countrycode, cli) values (?, ?, ?, ?, ?, ?) 2008-08-04 23:54:15,171 WARN [org.hibernate.util.JDBCExceptionReporter] SQL Error: 1213, SQLState: 40001 2008-08-04 23:54:15,187 ERROR [org.hibernate.util.JDBCExceptionReporter] Deadlock found when trying to get lock; try restarting transaction
-
3. Re: ManyToOne wont persist. help?
admin.admin.email.tld Aug 6, 2008 8:22 PM (in response to hcgpragt)are you running load tests or accessing the EntityManager in a servlet (not thread safe)?
you should post this on the hibernate forum.
-
4. Re: ManyToOne wont persist. help?
hcgpragt Aug 6, 2008 8:38 PM (in response to hcgpragt)I'm using the entity manager from the ejb3 container (Jboss4)
The reason I'm posting here is that the only thing I can come up with to explain the error is the transaction demarcation
Is there anything obviously wrong with my code which I'm just overlooking?
H
ps. Thanks for looking!
-
5. Re: ManyToOne wont persist. help?
dhinojosa Aug 7, 2008 6:55 AM (in response to hcgpragt)I bet your mysql log file will hold many answers for you.
-
6. Re: ManyToOne wont persist. help?
hcgpragt Aug 17, 2008 12:49 PM (in response to hcgpragt)solved.
The answer was to store the input in the database and from there handle the data.
End of deadlocks .
Hurray! -
7. Re: ManyToOne wont persist. help?
srinivas0731 Feb 6, 2009 9:55 AM (in response to hcgpragt)Hi Hugo Pragt
I have also got the same problem and i am unable to solve it could you please help me in resolving the issue.
I mean could please explain me with more details, how did you solve it?
Thank you
Srinivas -
8. Re: ManyToOne wont persist. help?
hcgpragt Feb 7, 2009 12:00 AM (in response to hcgpragt)Hi Srinivas Rao,
It's a bit late here now, but I will look the code up for you tomorrow.
Unless you are really in panic-mode?Cheers,
Hugo
-
9. Re: ManyToOne wont persist. help?
srinivas0731 Feb 7, 2009 7:54 AM (in response to hcgpragt)Hi Hugo,
Thanks for your concern. As I was desperate to get the issue resolved.
Without any thought, I have requested you. I am really in panic-mode.So is there any possibility of meeting you on any chat tool. otherwise ask me some queries that can bring you more clarity on my issue or suggest me how to resolve.
Also please let me know your convenient timing(time zone). So that I can get in touch with you in that time.
Please help me.
Thank You,
Srinivas -
10. Re: ManyToOne wont persist. help?
hcgpragt Feb 7, 2009 8:38 PM (in response to hcgpragt)Hi Srinivas,
I've had a look at the code And I'm able to call
em.persist(cdr)
The
two telephone numbers have the annotations:@ManyToOne(cascade={Cascasdetype.Merge,Cascadetype.PERSIST})
Things you could check:
- The annotations must be on the getters (not the setters) of the fields
- when you call merge instead of persists I get deadocks (merge keeps a lock maybe?)
- When you set a transactiontype annotation it only has effect on a business method. I found that that means a method called via the interface of an ejb.
I'll be available for the next few hours on msn via hotmail account : hcgragt
wish you succes,
Hugo
-
11. Re: ManyToOne wont persist. help?
hcgpragt Feb 8, 2009 7:26 PM (in response to hcgpragt)I created this separate method for storing telephone numbers:
@TransactionAttribute(TransactionAttributeType.REQUIRED) public TelephoneNumber getPhoneNumber (String cli, TelephoneNumberType type ) throws TelephonenumberCreateException { TelephoneNumber telnr = axeutil.createTelephoneNumber(cli, type); if (telnr == null) { return null; } return em.merge(telnr); }
This method is called from another EJB.
This EJB is the factory class for CDR's:cdr.setAnumber(getPhoneNumber(s[AxeCDR.CALLING_PARTY_NR], s[AxeCDR.A_SUBSCRIBER_NR_TYPE]))
After the CDR is created I then persist it.
But the telephonenumbers in the CDR are already stored and thus managed by Entity manager.I probably overdone it, but at least it works.
If it works don't try to fix itHope it helps!