Hi
I have now found a pattern in this strange behaviour and it is probably wrong usage of the JPA.
I have found out that I do not have to redeploy my ear file to recreate my problem. If I restart the server and executes the following client code ... everything works fine:
private static void testOneToMany() {
final AuServices auServices;
try {
final InitialContext ctx = new InitialContext();
auServices = (AuServices) ctx.lookup(AuServices.class.getName());
// Test that IMEI number 356828001349104 is not blocked
try {
if (auServices.isBlocked("356828001349104")) {
throw new RuntimeException();
} else {
System.out.println("isBlocked IMEI number 356828001349104 is not blocked succed!");
}
} catch (NoPhoneException e) {
throw new RuntimeException(e.getMessage(), e);
}
} catch (NamingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
If I execute the following code ... the application breaks ... but without any errors in the log file.
private static void testOneToMany() {
final AuServices auServices;
final AucoreTest aucoreTest;
try {
final InitialContext ctx = new InitialContext();
auServices = (AuServices) ctx.lookup(AuServices.class.getName());
aucoreTest = (AucoreTest) ctx.lookup(AucoreTest.class.getName());
// First delete data
aucoreTest.deleteTestData();
// Create standard test data
aucoreTest.createTestData();
// Test that IMEI number 356828001349104 is not blocked
try {
if (auServices.isBlocked("356828001349104")) {
throw new RuntimeException();
} else {
System.out.println("isBlocked IMEI number 356828001349104 is not blocked succed!");
}
} catch (NoPhoneException e) {
throw new RuntimeException(e.getMessage(), e);
}
} catch (NamingException e) {
e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
}
}
The only difference here is that I first delete my test data and thereafter recreate it with two different methods on a stateless session bean.
The code is shown below:
public void createTestData() {
// First create an address
final Stairway stairway = new Stairway("101", "95", "XXX", "27", "E", "9999", "9999", Stairway.Status.LOCKED);
em.persist(stairway);
// Then create a door unit
final DoorUnit doorUnit1 = new DoorUnit(stairway, "XXX", "1230989648B8", "123BA0992A2B2CF51C17404F125B827D");
em.persist(doorUnit1);
final DoorUnit doorUnit2 = new DoorUnit(stairway, "XXX", "1230989648A4", "123350F9EAAB2CF51C17404F125B827D");
em.persist(doorUnit2);
// Create a distributor
final Distributor distributorFK = new Distributor("FK", "XXXXXXX a/s");
em.persist(distributorFK);
final Distributor distributorBK = new Distributor("BK", "XXXXXXX a/s");
em.persist(distributorBK);
// Create a Mobile phone
final MobilePhone mobilePhone1 = new MobilePhone("+46", "999999999", "356828001349104", MobilePhone.StatusIMEI.LOCKED, MobilePhone.StatusBlocked.NONEWBLOCKED);
em.persist(mobilePhone1);
final MobilePhone mobilePhone2 = new MobilePhone("+46", "999999999", "354007001514932", MobilePhone.StatusIMEI.LOCKED, MobilePhone.StatusBlocked.NONEWBLOCKED);
em.persist(mobilePhone2);
final MobilePhone mobilePhoneFK = new MobilePhone("+45", "99999999", null, MobilePhone.StatusIMEI.UNLOCKED, MobilePhone.StatusBlocked.NONEWBLOCKED);
em.persist(mobilePhoneFK);
// DistMob relation
DistMob distMob = new DistMob(distributorFK, mobilePhone1, DistMob.Status.UNBLOCKED);
em.persist(distMob);
distMob = new DistMob(distributorBK, mobilePhone1, DistMob.Status.UNBLOCKED);
em.persist(distMob);
distMob = new DistMob(distributorFK, mobilePhone2, DistMob.Status.UNBLOCKED);
em.persist(distMob);
distMob = new DistMob(distributorBK, mobilePhone2, DistMob.Status.UNBLOCKED);
em.persist(distMob);
// Finally the access entities
// Valid
Date startAccess;
Date endAccess;
try {
startAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20070101000000");
endAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20091231235959");
} catch (ParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
Access access = new Access(doorUnit1, distributorFK, mobilePhone1, startAccess, endAccess);
em.persist(access);
try {
startAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20070101000000");
endAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20091231235959");
} catch (ParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
access = new Access(doorUnit2, distributorBK, mobilePhone1, startAccess, endAccess);
em.persist(access);
try {
startAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20070101000000");
endAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20091231235959");
} catch (ParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
access = new Access(doorUnit1, distributorBK, mobilePhone2, startAccess, endAccess);
em.persist(access);
try {
startAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20070101000000");
endAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20091231235959");
} catch (ParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
access = new Access(doorUnit2, distributorBK, mobilePhone2, startAccess, endAccess);
em.persist(access);
// Expired
try {
startAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20070101000000");
endAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20070627235959");
} catch (ParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
access = new Access(doorUnit1, distributorFK, mobilePhone1, startAccess, endAccess);
em.persist(access);
// Not yet valid
try {
startAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20080101000000");
endAccess = new SimpleDateFormat("yyyyMMddHHmmss").parse("20090627235959");
} catch (ParseException e) {
throw new RuntimeException(e.getMessage(), e);
}
access = new Access(doorUnit1, distributorFK, mobilePhone1, startAccess, endAccess);
em.persist(access);
}
public void deleteTestData() {
deleteDataFromTable("Entry");
deleteDataFromTable("Access");
deleteDataFromTable("DistMob");
deleteDataFromTable("MobilePhone");
deleteDataFromTable("Distributor");
deleteDataFromTable("DoorUnit");
deleteDataFromTable("Stairway");
}
private void deleteDataFromTable(final String tableName) {
final List objects = em.createQuery("SELECT t FROM " + tableName + " t").getResultList();
for (Object object : objects) {
em.remove(object);
}
}
I can not figure out why this deletion and recreation breaks the server .... But if I restart the server and removes the deletion and recreation ... everything works fine.
What is it that I have misunderstood?
/ Kasper
________________________________
Fra: Eve Pokua [mailto:gorgeous65_at_msn.com]
Sendt: 9. juli 2007 18:53
Til: persistence_at_glassfish.dev.java.net
Emne: RE: SV: @OneToMany problem
Could you also send some code of the client, it might be just a little mistake, if it is not error.
eve
________________________________
Date: Mon, 9 Jul 2007 12:01:51 +0200
From: Kasper.Moller_at_tietoenator.com
To: persistence_at_glassfish.dev.java.net
Subject: SV: @OneToMany problem
Hello
I have a problem using a @OneToMany relationship. I have to two classes (MobilePhone and DistMob) defined at the end: It is a bidirectional relationship where DistMob can have one MobilePhone and MobilePhone can have many DistMobs.
My application deploys without any problem on glassfish 1 stable release. The problem first occurs at runtime. After first deployment everything works fine ... retrieving a MobilePhone with the follwing code executes normally and mobilePhone.getDistMobs() gives me the correct number of DistMobs being in the database.
public boolean isBlocked(final String imeiNumber) throws NoPhoneException {
if (imeiNumber == null || "".equals(imeiNumber.trim())) {
throw new IllegalArgumentException("Argument null or empty!");
}
final MobilePhone mobilePhone = mobilePhoneFinder.findByImeiNumber(em, imeiNumber);
boolean blocked = true;
for (DistMob distMob : mobilePhone.getDistMobs()) {
if (DistMob.Status.UNBLOCKED.equals(distMob.getStatus())) {
blocked = false;
break;
}
}
return blocked;
}
My problem occurs when I redeploy my application ... at deploy time there is still no errors .... But at runtime will mobilePhone.getDistMobs() retrieve 0 elements. I am 100% sure that no one else is using my database and that it is same code which is deploy. I can not figure out what the problem might be.
The behaviour changes some times ... but I can not find a pattern.
package com.tietoenator.bekey.aucore.persistence;
import javax.persistence.*;
import java.util.List;
/**
* User: mollekas
* Date: 2007-06-26
* Time: 14:34:59
*/
@Entity
public class MobilePhone {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
private String prefix;
public void setPrefix(final String prefix) {
this.prefix = prefix;
}
public String getPrefix() {
return prefix;
}
private String number;
private String imeiNumber;
private String statusImei;
private String statusBlocked;
@OneToMany(mappedBy = "mobilePhone")
private List<DistMob> distMobs;
@OneToMany(mappedBy = "mobilePhone")
private List<Access> accesses;
public List<Access> getAccesses() {
return accesses;
}
public List<DistMob> getDistMobs() {
return distMobs;
}
public void setNumber(final String number) {
this.number = number;
}
public void setImeiNumber(final String imeiNumber) {
this.imeiNumber = imeiNumber;
}
public void setStatusImei(final StatusIMEI statusImeiIMEI) {
this.statusImei = statusImeiIMEI.getCode();
}
public void setStatusBlocked(final StatusBlocked statusBlocked) {
this.statusBlocked = statusBlocked.getCode();
}
public String getNumber() {
return number;
}
public String getImeiNumber() {
return imeiNumber;
}
public StatusIMEI getStatusImei() {
try {
return StatusIMEI.getStatus(statusImei);
} catch (IllegalStateException e) {
throw new IllegalStateException("Status code unknown for mobile phone with PK: " + id, e);
}
}
public StatusBlocked getStatusBlocked() {
try {
return StatusBlocked.getStatus(statusBlocked);
} catch (IllegalStateException e) {
throw new IllegalStateException("Status code unknown for mobile phone with PK: " + id, e);
}
}
public MobilePhone(final String prefix, final String number, final String imeiNumber, final StatusIMEI statusIMEI, final StatusBlocked statusBlocked) {
this.prefix = prefix;
this.number = number;
this.imeiNumber = imeiNumber;
this.statusImei = statusIMEI.getCode();
this.statusBlocked = statusBlocked.getCode();
}
public MobilePhone() {
}
public static class StatusIMEI {
/**
* Blocked
*/
public final static StatusIMEI LOCKED = new StatusIMEI("LOCKED");
/**
* Unblocked
*/
public final static StatusIMEI UNLOCKED = new StatusIMEI("UNLOCKED");
private final String code;
private StatusIMEI(final String code) {
this.code = code;
}
public String getCode() {
return code;
}
public static StatusIMEI getStatus(final String statusCode){
if(LOCKED.getCode().equals(statusCode)){
return LOCKED;
}
else if(UNLOCKED.getCode().equals(statusCode)){
return UNLOCKED;
}
else{
throw new IllegalStateException("Unknown staus code detected. Code was: " + statusCode);
}
}
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final StatusIMEI statusIMEI = (StatusIMEI) o;
if (code != null ? !code.equals(statusIMEI.code) : statusIMEI.code != null) return false;
return true;
}
public int hashCode() {
return (code != null ? code.hashCode() : 0);
}
}
public static class StatusBlocked {
/**
* Blocked
*/
public final static StatusBlocked NEWBLOCKED = new StatusBlocked("NEWBLOCKED");
/**
* Unblocked
*/
public final static StatusBlocked NONEWBLOCKED = new StatusBlocked("NONEWBLOCKED");
private final String code;
private StatusBlocked(final String code) {
this.code = code;
}
public String getCode() {
return code;
}
public static StatusBlocked getStatus(final String statusCode){
if(NEWBLOCKED.getCode().equals(statusCode)){
return NEWBLOCKED;
}
else if(NONEWBLOCKED.getCode().equals(statusCode)){
return NONEWBLOCKED;
}
else{
throw new IllegalStateException("Unknown staus code detected. Code was: " + statusCode);
}
}
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final StatusBlocked statusBlocked = (StatusBlocked) o;
if (code != null ? !code.equals(statusBlocked.code) : statusBlocked.code != null) return false;
return true;
}
public int hashCode() {
return (code != null ? code.hashCode() : 0);
}
}
}
package com.tietoenator.bekey.aucore.persistence;
import javax.persistence.*;
/**
* User: mollekas
* Date: 2007-06-26
* Time: 14:29:18
*/
@Entity
public class DistMob {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private String id;
@ManyToOne
@JoinColumn(name = "DistributorFK")
private Distributor distributor;
@ManyToOne
@JoinColumn(name = "MobilePhoneFK")
private MobilePhone mobilePhone;
private String status;
public void setDistributor(final Distributor distributor) {
this.distributor = distributor;
}
public void setMobilePhone(final MobilePhone mobilePhone) {
this.mobilePhone = mobilePhone;
}
public void setStatus(final Status status) {
this.status = status.getCode();
}
public Distributor getDistributor() {
return distributor;
}
public MobilePhone getMobilePhone() {
return mobilePhone;
}
public Status getStatus() {
try {
return Status.getStatus(status);
} catch (IllegalStateException e) {
throw new IllegalStateException("Status code unknown for stairway with PK: " + id, e);
}
}
public DistMob(final Distributor distributor, final MobilePhone mobilePhone, final Status status) {
this.distributor = distributor;
this.mobilePhone = mobilePhone;
this.status = status.getCode();
}
public DistMob() {
}
public static class Status {
/**
* Blocked
*/
public final static Status BLOCKED = new Status("BLOCKED");
/**
* Unblocked
*/
public final static Status UNBLOCKED = new Status("UNBLOCKED");
private final String code;
private Status(final String code) {
this.code = code;
}
public String getCode() {
return code;
}
public static Status getStatus(final String statusCode){
if(BLOCKED.getCode().equals(statusCode)){
return BLOCKED;
}
else if(UNBLOCKED.getCode().equals(statusCode)){
return UNBLOCKED;
}
else{
throw new IllegalStateException("Unknown staus code detected. Code was: " + statusCode);
}
}
public boolean equals(final Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
final Status status = (Status) o;
if (code != null ? !code.equals(status.code) : status.code != null) return false;
return true;
}
public int hashCode() {
return (code != null ? code.hashCode() : 0);
}
}
}
Med venlig hilsen / Kind regards
Kasper Møller
Konsulent / Consultant
TietoEnator A/S
Healthcare & Welfare (HCWD-CSU)
Direct: +45 72 30 62 93
Mobile: +45 25 42 36 50
E-mail: kasper.moller_at_tietoenator.com <mailto:kasper.moller_at_tietoenator.com>
Vesterbrogade 149
DK - 1620 København V
<
http://www.tietoenator.com <
http://www.tietoenator.com> >
________________________________
The next generation of MSN Hotmail has arrived - Windows Live Hotmail <
http://www.newhotmail.co.uk>