users@glassfish.java.net

Re: select after insert issue

From: Davy De Durpel <Davy.De.Durpel_at_isencia.be>
Date: Wed, 03 May 2006 10:57:14 +0200
Hi,

Ok, that are a lot of logical questions from several mails but I don't think I can provide an answer to all of them because I'm rather new to the stuff.  The thing is that I tried to use as much as possible the default values because I like to develop by exception. 

Something about my development environment:

- JDK 1.5
- Glassfish B42 and B46
- JavaDB (the one that comes with Glassfish)
- Eclipse 3.2 M6
- WTP 1.5 M6
- Glassfish plugin 0.2.1
- Wicket 1.2 RC2

What follows are the cleaned up Entity pojo's (I removed comments, imports and setters) , the code I use to persist and to do the select and the data model.  At the end there is some more information about the application and some answers to the questions.

-----------------------------------------------------------------------------
@Entity
@IdClass(ReservationPK.class)
@Table(name="RESERVATIONS")
public class Reservation implements ReservationRemote {
   
    private static final long serialVersionUID = 7731097732230332469L;
   
    private Integer ID;
    private Asset asset;
    private Integer assetID;
    private User user;
    private Date dateFrom;
    private Date dateTo;
    private User CreatedBy;
    private Date creationDate;
   
    @ManyToOne
    @JoinColumn(name = "ASSET_ID", referencedColumnName="ID")
    public Asset getAsset() {
        return asset;
    }
    @ManyToOne
    @JoinColumn(name="CREATED_BY", referencedColumnName="ID")
    public User getCreatedBy() {
        return CreatedBy;
    }
    @Column(name="CREATION_DATE")
    @Temporal(TemporalType.DATE)
    public Date getCreationDate() {
        return creationDate;
    }
    @Column(name="DATE_FROM")
    @Temporal(TemporalType.DATE)
    public Date getDateFrom() {
        return dateFrom;
    }
    @Column(name="DATE_TO")
    @Temporal(TemporalType.DATE)
    public Date getDateTo() {
        return dateTo;
    }
    @Id
    @Column(name="ID")
    public Integer getID() {
        return ID;
    }
    @Id
    @Column(name="ASSET_ID", nullable=false, updatable=false, insertable=false)
    public Integer getAssetID() {
        return assetID;
    }
    @ManyToOne(targetEntity=User.class)
    @JoinColumn(name="USER_ID", referencedColumnName="ID")
    public User getUser() {
        return user;
    }
}

-----------------------------------------------------------------------------
@Entity
@Table(name="ASSETS")
public class Asset implements AssetRemote {
    private static final long serialVersionUID = 7293500542981293826L;
   
    private Integer ID;
    private AssetType assetType;
    private String location;
    private User owner;
    private Integer minReservations;
    private Integer maxReservations;
    private User createdBy;
    private Date creationDate;

    @ManyToOne
    @JoinColumn(name="ASSET_TYPE_ID", referencedColumnName="ID")
    public AssetType getAssetType() {
        return assetType;
    }
    @ManyToOne
    @JoinColumn(name="CREATED_BY", referencedColumnName="ID")
    public User getCreatedBy() {
        return createdBy;
    }
    @Column(name="CREATION_DATE")
    @Temporal(TemporalType.DATE)
    public Date getCreationDate() {
        return creationDate;
    }
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    public Integer getID() {
        return ID;
    }
    @Column(name="LOCATION")
    public String getLocation() {
        return location;
    }
    @Column(name="MAX_RESERVATION")
    public Integer getMaxReservations() {
        return maxReservations;
    }
    @Column(name="MIN_RESERVATION")
    public Integer getMinReservations() {
        return minReservations;
    }
    @ManyToOne
    @JoinColumn(name="OWNER_ID", referencedColumnName="ID")
    public User getOwner() {
        return owner;
    }
}
-----------------------------------------------------------------------------
@Stateless
public class Reservations implements Serializable, ReservationsRemote {
   
    private static final long serialVersionUID = 1062786124637158763L;

    @PersistenceContext(unitName="AssMaEM")
    EntityManager em;

    @SuppressWarnings("unchecked")
    public List<Reservation> findAllForUser(int first, int count, String sortProperty, boolean sortAsc, User user) {

        String ejbql = "SELECT c FROM Reservation c WHERE c.user = :user";
        Query query = em.createQuery(ejbql);
        query.setParameter("user", user);
       
        return query.getResultList();
    }

    public void update(Reservation reservation) {
        Reservation mergedReservation = em.merge(reservation);
        em.persist(mergedReservation);       
    }
   
    public ReservationRemote create(Reservation reservation) {
        em.persist(reservation);
        return reservation;       
    }
}
-----------------------------------------------------------------------------
CREATE SCHEMA ASSMA;

CREATE TABLE USERS
(
   ID INTEGER PRIMARY KEY not null GENERATED ALWAYS AS IDENTITY,
   USER_NAME CHAR(8) not null,
   FULL_NAME VARCHAR(50) not null,
   PASSWORD VARCHAR(30) not null,
   EMAIL_ADDRESS VARCHAR(80)
);

CREATE TABLE USERS_ROLES
(
   USER_ID INTEGER not null,
   ROLE_ID INTEGER not null,
   CONSTRAINT USERS_ROLES_PK PRIMARY KEY (USER_ID,ROLE_ID)
);

CREATE TABLE ROLES
(
   ID INTEGER PRIMARY KEY not null GENERATED ALWAYS AS IDENTITY,
   NAME VARCHAR(50) not null
);

CREATE TABLE RESERVATIONS
(
   ID INTEGER not null GENERATED BY DEFAULT AS IDENTITY,
   ASSET_ID INTEGER,
   USER_ID INTEGER not null,
   DATE_FROM DATE,
   DATE_TO DATE,
   CREATED_BY INTEGER not null,
   CREATION_DATE DATE not null,
   CONSTRAINT RESERVATIONS_PK PRIMARY KEY (ID,ASSET_ID)
);

CREATE TABLE ASSETS
(
   ID INTEGER PRIMARY KEY not null GENERATED ALWAYS AS IDENTITY,
   ASSET_TYPE_ID INTEGER not null,
   LOCATION VARCHAR(50),
   OWNER_ID INTEGER not null,
   MIN_RESERVATION INTEGER,
   MAX_RESERVATION INTEGER,
   CREATED_BY INTEGER not null,
   CREATION_DATE DATE not null
);

CREATE TABLE ASSET_TYPES
(
   ID INTEGER PRIMARY KEY not null GENERATED ALWAYS AS IDENTITY,
   NAME VARCHAR(20) not null,
   DESCRIPTION VARCHAR(50) not null
);
-----------------------------------------------------------------------------

- ReservationPK is just a bean with the 2 Integers that make up the ID and with getters and setters (no annotations)
- All have remote interfaces with getters and setters for all of the properties
- I didn't put any cascading restrictions in my code and in my database because this project is only an internal test project and I want to keep things simple
- The data model is the complete model I use for this test project. It is far from being perfect and will not work in a production environment.  One of my tests is to see how easy it is to write Entity beans on an existing data model.
- Almost everything I use is still in beta phase but then I like to live on the edge ;-)
- I like Glassfish allot but I love Wicket

- I think that all entities are detached entities because I need to call em.merge before doing an update.
- I do not know anything about cascade settings since I'm using the default but I know that when I do a persist of a new User that has Roles that don't exist in the database, that those roles are also persisted.
- There are no foreign keys on the database and most of them have Identity fields
- I did however define the necessary relationships between the Entity beans

Now somebody has an idea what this mortal is doing wrong?

Byeee...

Gordon Yorke wrote:
Hello,
   We are going to need more detail.  What is the cascade settings on the relationships from Reservation to User and Asset?  Are they Cascade PERSIST or cascade ALL?  These pre-existing User and Asset objects are they managed entities or detached entities?  Can you provide the code that is performing this operation?  Are there unique constraints on the database tables?
--Gordon

-----Original Message-----
From: Marina.Vatkina@Sun.COM [mailto:Marina.Vatkina@Sun.COM]On Behalf Of
Marina Vatkina
Sent: Tuesday, May 02, 2006 12:44 PM
To: users@glassfish.dev.java.net; persistence
Subject: Re: select after insert issue


Hi Davy,

CC-ing persistence alias.
Is it a Java SE or a Java EE application? Do you navigate to the related
objects via getters?

thanks,
-marina

Davy De Durpel wrote:
  
Hi,

I have a strange behavior and I have it on build 42 and 46 (the only 2 I
tested).

The problem in short is that when I do a persist of a new entity and
then I do a select to retrieve all entities from the database, then all
referenced objects are empty (all properties are Null).  No way to get
them back then restarting the application.  In all other situations
(selects, updates) I don't have the problem but things go wrong as soon
as I persist a new Entity to the database.

I will try to explain in more detail.

I have a table 'Reservation' that contains a link to a table 'Asset' and
a table 'User'.
I execute this query to get all the reservations for a certain user:
'SELECT c FROM Reservation c WHERE c.user = :user'
Everything is left by default so it should be using eager fetching.  The
result is correct and also the User and Asset information is retrieved
from the database.
I now create a new Reservation with some default values.  I also add an
existing Asset and User object (detached from the entity manager).
I use em.persist to save the reservation in the database and I can
clearly see that this is done in a correct way.
I then execute the same query again to retrieve all Reservations for the
current user from the database but now my 'User' and 'Asset' objects
have all fields initialized to Null values.

I also tried it with other Entity beans and I have the same behavior.

Any idea what could be causing this behavior or do I need to provide
more details?

Byeee...

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net

    

---------------------------------------------------------------------
To unsubscribe, e-mail: users-unsubscribe@glassfish.dev.java.net
For additional commands, e-mail: users-help@glassfish.dev.java.net