persistence@glassfish.java.net

SV: RE: SV: _at_OneToMany problem

From: <Kasper.Moller_at_tietoenator.com>
Date: Tue, 10 Jul 2007 08:15:22 +0200

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>