Server tests
diff --git a/JPA-RS/org.eclipse.persistence.jpars.test/WebContent/META-INF/MANIFEST.MF b/JPA-RS/org.eclipse.persistence.jpars.test/WebContent/META-INF/MANIFEST.MF
new file mode 100644
index 0000000..5e94951
--- /dev/null
+++ b/JPA-RS/org.eclipse.persistence.jpars.test/WebContent/META-INF/MANIFEST.MF
@@ -0,0 +1,3 @@
+Manifest-Version: 1.0

+Class-Path: 

+

diff --git a/JPA-RS/org.eclipse.persistence.jpars.test/WebContent/WEB-INF/sun-web.xml b/JPA-RS/org.eclipse.persistence.jpars.test/WebContent/WEB-INF/sun-web.xml
new file mode 100644
index 0000000..ecd59f9
--- /dev/null
+++ b/JPA-RS/org.eclipse.persistence.jpars.test/WebContent/WEB-INF/sun-web.xml
@@ -0,0 +1,11 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE sun-web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Application Server 9.0 Servlet 2.5//EN" "http://www.sun.com/software/appserver/dtds/sun-web-app_2_5-0.dtd">
+<sun-web-app error-url="">
+  <context-root>/org.eclipse.persistence.jpars.test.server</context-root>
+  <class-loader delegate="true"/>
+  <jsp-config>
+    <property name="keepgenerated" value="true">
+      <description>Keep a copy of the generated servlet class java code.</description>
+    </property>
+  </jsp-config>
+</sun-web-app>
diff --git a/JPA-RS/org.eclipse.persistence.jpars.test/eclipselink.jpa-rs.properties b/JPA-RS/org.eclipse.persistence.jpars.test/eclipselink.jpa-rs.properties
index 2d01e5a..367eb70 100644
--- a/JPA-RS/org.eclipse.persistence.jpars.test/eclipselink.jpa-rs.properties
+++ b/JPA-RS/org.eclipse.persistence.jpars.test/eclipselink.jpa-rs.properties
@@ -1,6 +1,6 @@
-javax.persistence.jdbc.driver=oracle.jdbc.OracleDriver

-javax.persistence.jdbc.url=jdbc:oracle:thin:@localhost:1521:XE

-javax.persistence.jdbc.user=tware

+javax.persistence.jdbc.driver=com.mysql.jdbc.Driver

+javax.persistence.jdbc.url=jdbc:mysql://localhost/eclipsedb

+javax.persistence.jdbc.user=eclipsetest

 javax.persistence.jdbc.password=password

 

 eclipselink.jdbc.read-connections.min=1

diff --git a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/crud/StaticCrudTests.java b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/crud/StaticCrudTests.java
index 6aae71a..b494b3d 100644
--- a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/crud/StaticCrudTests.java
+++ b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/crud/StaticCrudTests.java
@@ -81,6 +81,7 @@
     public void testCreateAndDelete() {

         StaticUser user = new StaticUser();;

         user.setName("Jim");

+        user.setId(1);

         persistenceContext.create(null, user);

         user = (StaticUser)persistenceContext.find("StaticUser", user.getId());

         

@@ -100,14 +101,17 @@
     public void testQuery(){

         StaticUser user = new StaticUser();

         user.setName("Jill");

+        user.setId(2);

         persistenceContext.create(null, user);

         

         user = new StaticUser();

         user.setName("Arthur");

+        user.setId(3);

         persistenceContext.create(null, user);

         

         user = new StaticUser();

         user.setName("Judy");

+        user.setId(4);

         persistenceContext.create(null, user);

         

         List<StaticUser> users = (List<StaticUser>)persistenceContext.query("User.all", null);

@@ -118,6 +122,7 @@
     public void testUpdate(){

         StaticUser user = new StaticUser();

         user.setName("Tom");

+        user.setId(5);

         persistenceContext.create(null, user);

         user = (StaticUser)persistenceContext.find("StaticUser", user.getId());

         user.setName("Thomas");

diff --git a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticAddress.java b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticAddress.java
index afef297..cda76aa 100644
--- a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticAddress.java
+++ b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticAddress.java
@@ -62,5 +62,4 @@
         this.user = user;

     }

     

-    

 }

diff --git a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticBid.java b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticBid.java
index aa9aa93..d989a90 100644
--- a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticBid.java
+++ b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticBid.java
@@ -13,8 +13,10 @@
 package org.eclipse.persistence.jpars.test.model;

 

 import javax.persistence.Entity;

+import javax.persistence.FetchType;

 import javax.persistence.GeneratedValue;

 import javax.persistence.Id;

+import javax.persistence.OneToOne;

 import javax.persistence.Table;

 import javax.persistence.Transient;

 

@@ -32,8 +34,10 @@
     

     private long time;

 

+    @OneToOne(fetch=FetchType.LAZY)

     private StaticUser user;

 

+    @OneToOne(fetch=FetchType.LAZY)

     private StaticAuction auction;

 

     public int getId() {

diff --git a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticUser.java b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticUser.java
index d57b375..9f5846e 100644
--- a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticUser.java
+++ b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/model/StaticUser.java
@@ -18,15 +18,34 @@
 import javax.persistence.Id;

 import javax.persistence.JoinColumn;

 import javax.persistence.JoinColumns;

-import javax.persistence.ManyToOne;

+import javax.persistence.NamedQueries;

 import javax.persistence.NamedQuery;

 import javax.persistence.OneToOne;

 import javax.persistence.Table;

 

-@NamedQuery(

+@NamedQueries({

+    @NamedQuery(

         name="User.all", 

         query="SELECT u FROM StaticUser u"

+    ),

+    @NamedQuery(

+            name="User.byId", 

+            query="SELECT u FROM StaticUser u where u.id = :id"

+    ),

+    @NamedQuery(

+        name="User.byName", 

+        query="SELECT u FROM StaticUser u where u.name = :name"

+    ),

+    @NamedQuery(

+        name="User.byNameOrId", 

+        query="SELECT u FROM StaticUser u where u.name = :name or u.id = :id"

     )

+    ,

+    @NamedQuery(

+        name="User.updateName", 

+        query="UPDATE StaticUser u SET u.name = :name where u.id = :id"

+    )

+})

 

 @Entity

 @Table(name="ST_AUC_USER")

@@ -68,6 +87,20 @@
     public void setAddress(StaticAddress address) {

         this.address = address;

     }

+    

+    public boolean equals(Object object){

+        if (object == null || !(object instanceof StaticUser)){

+            return false;

+        }

+        StaticUser user = (StaticUser)object;

+        if (address == null && user.getAddress() != null){

+            return false;

+        }

+        if (name == null && user.getName() != null){

+            return false;

+        }

+        return id == user.getId() && name.equals(user.getName()) && (address == null || address.getId() == user.getAddress().getId());

+    }

 

     

 }

diff --git a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/server/ServerCrudTest.java b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/server/ServerCrudTest.java
index 2665473..d517110 100644
--- a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/server/ServerCrudTest.java
+++ b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/server/ServerCrudTest.java
@@ -7,22 +7,25 @@
 import java.io.ByteArrayInputStream;

 import java.io.ByteArrayOutputStream;

 import java.io.CharArrayReader;

+import java.io.IOException;

 import java.net.URI;

 import java.net.URISyntaxException;

+import java.util.ArrayList;

 import java.util.HashMap;

+import java.util.List;

 import java.util.Map;

 

 import javax.persistence.EntityManager;

 import javax.persistence.EntityManagerFactory;

 import javax.persistence.Persistence;

 import javax.ws.rs.core.MediaType;

-import javax.xml.bind.JAXBElement;

 import javax.xml.bind.JAXBException;

 import javax.xml.bind.PropertyException;

 import javax.xml.bind.Unmarshaller;

 import javax.xml.transform.stream.StreamSource;

 

 import org.eclipse.persistence.config.PersistenceUnitProperties;

+import org.eclipse.persistence.config.QueryHints;

 import org.eclipse.persistence.jaxb.JAXBContext;

 import org.eclipse.persistence.jaxb.JAXBContextFactory;

 import org.eclipse.persistence.jpa.rs.PersistenceContext;

@@ -43,11 +46,13 @@
 

 import com.sun.jersey.api.client.Client;

 import com.sun.jersey.api.client.ClientResponse;

+import com.sun.jersey.api.client.ClientResponse.Status;

 import com.sun.jersey.api.client.WebResource;

 

 public class ServerCrudTest {

     

     public static final String SERVER_URI = "http://localhost:8080/org.eclipse.persistence.jpars.test.server/jpa-rs/";

+    public static final String DEFAULT_PU = "auction-static";

     protected static Client client = null;

     protected static Unmarshaller unmarshaller = null;

     protected static PersistenceContext context = null;

@@ -75,7 +80,7 @@
         factory.setMetadataStore(new DatabaseMetadataStore());

         factory.getMetadataStore().setProperties(properties);

         factory.getMetadataStore().clearMetadata();

-        EntityManagerFactory emf = Persistence.createEntityManagerFactory("auction-static", properties);

+        EntityManagerFactory emf = Persistence.createEntityManagerFactory(DEFAULT_PU, properties);

         try{

             context = factory.bootstrapPersistenceContext("auction-static", emf, new URI("http://localhost:8080/JPA-RS/"), false);

         } catch (URISyntaxException e){

@@ -90,47 +95,646 @@
     

     @Test

     public void testRead(){

-        WebResource webResource = client.resource(SERVER_URI + "auction-static/entity/StaticBid/" + bid1Id);

-        String result = webResource.accept(MediaType.APPLICATION_JSON).get(String.class);

-        StaticBid bid = null;

-        try {

-            bid = (StaticBid)context.unmarshalEntity("StaticBid", null, MediaType.APPLICATION_JSON_TYPE, new ByteArrayInputStream(result.getBytes()));

-        } catch (JAXBException e){

-            fail("Exception thrown unmarshalling: " + e);

-        }

+        StaticBid bid = restRead(bid1Id, "StaticBid", StaticBid.class);

         assertTrue("Wrong big retrieved.", bid.getBid() == 110);

         assertTrue("No user for Bid", bid.getUser() != null);

         assertTrue("No auction for Bid", bid.getAuction() != null);

+        bid = dbRead(bid1Id, StaticBid.class);

+        assertTrue("Wrong big in DB.", bid.getBid() == 110);

+        assertTrue("No user for Bid in DB", bid.getUser() != null);

+        assertTrue("No auction for Bid in DB", bid.getAuction() != null);

+    }

+    

+    @Test

+    public void testReadXML(){

+        StaticBid bid = restRead(bid1Id, "StaticBid", StaticBid.class, DEFAULT_PU, MediaType.APPLICATION_XML_TYPE);

+        assertTrue("Wrong big retrieved.", bid.getBid() == 110);

+        assertTrue("No user for Bid", bid.getUser() != null);

+        assertTrue("No auction for Bid", bid.getAuction() != null);

+        bid = dbRead(bid1Id, StaticBid.class);

+        assertTrue("Wrong big in DB.", bid.getBid() == 110);

+        assertTrue("No user for Bid in DB", bid.getUser() != null);

+        assertTrue("No auction for Bid in DB", bid.getAuction() != null);

+    }

+    

+    @Test

+    public void testReadNonExistant(){

+        RestCallFailedException exc = null;

+        try{

+            restRead(0, "StaticBid", StaticBid.class);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non-existant object read.", exc != null);

+        assertTrue("Wrong exception thrown for non-existant object read.", exc.getResponseStatus().equals(Status.NOT_FOUND));

+    }

+    

+    @Test

+    public void testReadNonExistantType(){

+        RestCallFailedException exc = null;

+        try{

+            restRead(1, "NonExistant", StaticBid.class);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non-existant object read.", exc != null);

+        assertTrue("Wrong exception thrown for non-existant object read.", exc.getResponseStatus().equals(Status.NOT_FOUND));

+    }

+    

+    @Test

+    public void testReadNonExistantPU(){

+        RestCallFailedException exc = null;

+        try{

+            restRead(1, "StaticBid", StaticBid.class, "non-existant", MediaType.APPLICATION_JSON_TYPE);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non-existant object read.", exc != null);

+        assertTrue("Wrong exception thrown for non-existant object read.", exc.getResponseStatus().equals(Status.NOT_FOUND));

     }

     

     @Test

     public void testUpdate(){

-        WebResource webResource = client.resource(SERVER_URI + "auction-static/entity/StaticBid/" + bid1Id);

-        String result = webResource.accept(MediaType.APPLICATION_JSON).get(String.class);

-        StaticBid bid = null;

-        try {

-            bid = (StaticBid)context.unmarshalEntity("StaticBid", null, MediaType.APPLICATION_JSON_TYPE, new ByteArrayInputStream(result.getBytes()));

+        StaticBid bid = restRead(bid1Id, "StaticBid", StaticBid.class);

+        bid.setBid(120);

+        bid = restUpdate(bid, "StaticBid", StaticBid.class);

+        assertTrue("Wrong big retrieved.", bid.getBid() == 120);

+        assertTrue("No user for Bid", bid.getUser() != null);

+        assertTrue("No auction for Bid", bid.getAuction() != null);

+        bid = dbRead(bid1Id, StaticBid.class);

+        assertTrue("Wrong big retrieved in db.", bid.getBid() == 120);

+        assertTrue("No user for Bid in db", bid.getUser() != null);

+        assertTrue("No auction for Bid in db", bid.getAuction() != null);

+        bid.setBid(110);

+        bid = restUpdate(bid, "StaticBid", StaticBid.class);

+    }

+    

+    @Test

+    public void testCreateDelete(){

+        StaticUser user = new StaticUser();

+        user.setName("Joe");

+        user.setId(100);

+        user = restCreate(user, "StaticUser", StaticUser.class);

+        assertTrue("Wrong big retrieved.", user.getName().equals("Joe"));

+        StaticUser dbUser = dbRead(user.getId(), StaticUser.class);

+        assertTrue("DB User not equal ", user.equals(dbUser));

+        restDelete(user.getId(), "StaticUser", StaticUser.class);

+        dbUser = dbRead(user.getId(), StaticUser.class);

+        assertTrue("User was not deleted.", dbUser == null);

+    }

+    

+    @Test

+    public void testCreateXML(){

+        StaticUser user = new StaticUser();

+        user.setName("Joe");

+        user.setId(101);

+        user = restCreate(user, "StaticUser", StaticUser.class, DEFAULT_PU,  MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_XML_TYPE);

+        assertTrue("Wrong big retrieved.", user.getName().equals("Joe"));

+        StaticUser dbUser = dbRead(user.getId(), StaticUser.class);

+        assertTrue("DB User not equal ", user.equals(dbUser));

+        restDelete(user.getId(), "StaticUser", StaticUser.class);

+        dbUser = dbRead(user.getId(), StaticUser.class);

+        assertTrue("User was not deleted.", dbUser == null);

+    }

+    

+    @Test

+    public void testCreateSequenced(){

+        StaticAuction auction = new StaticAuction();

+        auction.setName("Laptop");

+        RestCallFailedException exc = null;

+        try{

+            auction = restCreate(auction, "StaticAuction", StaticAuction.class);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for create with sequencing.", exc != null);

+        assertTrue("Wrong exception thrown for create with sequencing. " + exc.getResponseStatus(), exc.getResponseStatus().equals(Status.BAD_REQUEST));

+

+    }

+    

+    @Test

+    public void testCreateNonExistant(){

+        StaticUser user = new StaticUser();

+        user.setName("Joe");

+        user.setId(102);

+        RestCallFailedException exc = null;

+        try{

+            user = restCreate(user, "NonExistant", StaticUser.class);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non-existant object create.", exc != null);

+        assertTrue("Wrong exception thrown for non-existant object create. " + exc.getResponseStatus(), exc.getResponseStatus().equals(Status.NOT_FOUND));

+    }

+    

+    @Test

+    public void testCreateNonExistantPersistenceUnit(){

+        StaticUser user = new StaticUser();

+        user.setName("Joe");

+        user.setId(103);

+        RestCallFailedException exc = null;

+        try{

+            user = restCreate(user, "StaticUser", StaticUser.class, "non-existant",  MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_XML_TYPE);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non-existant object create.", exc != null);

+        assertTrue("Wrong exception thrown for non-existant object create.", exc.getResponseStatus().equals(Status.NOT_FOUND));

+    }

+   

+    /**

+     * Removed.  Requires a JSON parsing feature to detect incorrect data

+

+    @Test

+    public void testCreateWrongType(){

+        

+        WebResource webResource = client.resource(SERVER_URI + DEFAULT_PU + "/entity/" + "StaticUser");

+        ByteArrayOutputStream os = new ByteArrayOutputStream();

+        try{

+            context.marshallEntity(new StaticBid(), MediaType.APPLICATION_JSON_TYPE, os);       

         } catch (JAXBException e){

             fail("Exception thrown unmarshalling: " + e);

         }

+        ClientResponse response = webResource.type(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON_TYPE).put(ClientResponse.class, os.toString());

+        Status status = response.getClientResponseStatus();

+        assertTrue("Wrong exception thrown for non-existant object read.", status.equals(Status.NOT_FOUND));

+    }

+    */

+    

+    @Test

+    public void testCreateGarbage(){

+        

+        WebResource webResource = client.resource(SERVER_URI + DEFAULT_PU + "/entity/" + "StaticUser");

+        ByteArrayOutputStream os = new ByteArrayOutputStream();

+        byte[] b = "Garbage".getBytes();

+        try{

+            os.write(b);

+        } catch (IOException e){

+            fail("Error serializing data: "+ e);

+        }

+        ClientResponse response = webResource.type(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON_TYPE).put(ClientResponse.class, os.toString());

+        Status status = response.getClientResponseStatus();

+        assertTrue("Wrong exception garbage write. " + status, status.equals(Status.INTERNAL_SERVER_ERROR));

+    }

+    

+    @Test

+    public void testUpdateXML(){

+        StaticBid bid = restRead(bid1Id, "StaticBid", StaticBid.class, DEFAULT_PU, MediaType.APPLICATION_XML_TYPE);

         bid.setBid(120);

-        webResource = client.resource(SERVER_URI + "auction-static/entity/StaticBid");

+        bid = restUpdate(bid, "StaticBid", StaticBid.class, DEFAULT_PU, MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_XML_TYPE);

+        assertTrue("Wrong big retrieved.", bid.getBid() == 120);

+        assertTrue("No user for Bid", bid.getUser() != null);

+        assertTrue("No auction for Bid", bid.getAuction() != null);

+        bid = dbRead(bid1Id, StaticBid.class);

+        assertTrue("Wrong big retrieved in db.", bid.getBid() == 120);

+        assertTrue("No user for Bid in db", bid.getUser() != null);

+        assertTrue("No auction for Bid in db", bid.getAuction() != null);

+        bid.setBid(110);

+        bid = restUpdate(bid, "StaticBid", StaticBid.class);

+    }

+    

+    @Test

+    public void testPostNewEntity(){

+        StaticAuction auction = new StaticAuction();

+        auction.setName("Computer");

+        auction = restUpdate(auction, "StaticAuction", StaticAuction.class);

+        assertTrue("Wrong User returned.", auction.getName().equals("Computer"));

+        assertTrue("User not sequenced.", auction.getId() > 0);

+        StaticAuction dbAuction = dbRead(auction.getId(), StaticAuction.class);

+        assertTrue("Wrong user retrieved in db.", auction.getName().equals(dbAuction.getName()));

+        restDelete(auction.getId(), "StaticAuction", StaticAuction.class);

+    }

+    

+    @Test

+    public void testUpdateNonExistant(){

+        StaticUser user = new StaticUser();

+        user.setName("Joe");

+        RestCallFailedException exc = null;

+        try{

+            user = restUpdate(user, "NonExistant", StaticUser.class);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non-existant object update.", exc != null);

+        assertTrue("Wrong exception thrown for non-existant object update. " + exc.getResponseStatus(), exc.getResponseStatus().equals(Status.NOT_FOUND));

+    }

+    

+    @Test

+    public void testUpdateNonExistantPersistenceUnit(){

+        StaticUser user = new StaticUser();

+        user.setName("Joe");

+        RestCallFailedException exc = null;

+        try{

+            user = restUpdate(user, "StaticUser", StaticUser.class, "non-existant",  MediaType.APPLICATION_XML_TYPE, MediaType.APPLICATION_XML_TYPE);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non-existant object create.", exc != null);

+        assertTrue("Wrong exception thrown for non-existant object create.", exc.getResponseStatus().equals(Status.NOT_FOUND));

+    }

+    

+    @Test

+    public void testUpdateGarbage(){

+        WebResource webResource = client.resource(SERVER_URI + DEFAULT_PU + "/entity/" + "StaticUser");

+        ByteArrayOutputStream os = new ByteArrayOutputStream();

+        byte[] b = "Garbage".getBytes();

+        try{

+            os.write(b);

+        } catch (IOException e){

+            fail("Error serializing data: "+ e);

+        }

+        ClientResponse response = webResource.type(MediaType.APPLICATION_JSON_TYPE).accept(MediaType.APPLICATION_JSON_TYPE).post(ClientResponse.class, os.toString());

+        Status status = response.getClientResponseStatus();

+        assertTrue("Wrong exception garbage write. " + status, status.equals(Status.BAD_REQUEST));

+    }

+    

+    @Test

+    public void testDeleteNonExistant(){

+        try{

+            restDelete(1000, "StaticUser", StaticUser.class);

+        } catch (RestCallFailedException e){

+            fail("Exception thrown for non-existant object delete.");

+        }

+    }

+    

+    @Test

+    public void testDeleteNonExistantType(){

+        RestCallFailedException exc = null;

+        try{

+            restDelete(1000, "NonExistant", StaticUser.class);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non-existant object delete.", exc != null);

+        assertTrue("Wrong exception thrown for non-existant object delete. " + exc.getResponseStatus(), exc.getResponseStatus().equals(Status.NOT_FOUND));

+    }

+    

+    @Test

+    public void testDeleteNonExistantPersistenceUnit(){

+        RestCallFailedException exc = null;

+        try{

+            restDelete(1000, "StaticUser", StaticUser.class, "non-existant");

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non-existant object delete.", exc != null);

+        assertTrue("Wrong exception thrown for non-existant object delete.", exc.getResponseStatus().equals(Status.NOT_FOUND));

+    }

+    

+    @Test

+    public void testNamedQuery(){

+        List<StaticUser> users = (List<StaticUser>)restNamedQuery("User.all", "StaticUser", null, null);

+        assertTrue("Incorrect Number of users found.", users.size() == 3);

+    }

+    

+    @Test

+    public void testNamedQueryParameter(){

+        Map<String, Object> parameters = new HashMap<String, Object>();

+        parameters.put("id", user1Id);

+        List<StaticUser> users = (List<StaticUser>)restNamedQuery("User.byId", "StaticUser", parameters, null);

+        assertTrue("Incorrect Number of users found.", users.size() == 1);

+        assertTrue("Wrong user returned", users.get(0).getId() == user1Id);

+    }

+    

+    @Test

+    public void testNamedQueryParameters(){

+        Map<String, Object> parameters = new HashMap<String, Object>();

+        parameters.put("id", user1Id);

+        parameters.put("name", "user2");

+        List<StaticUser> users = (List<StaticUser>)restNamedQuery("User.byNameOrId", "StaticUser", parameters, null);

+        assertTrue("Incorrect Number of users found.", users.size() == 2);

+    }

+    

+    @Test

+    public void testNamedQueryWrongParameter(){

+        RestCallFailedException exc = null;

+        try{

+            Map<String, Object> parameters = new HashMap<String, Object>();

+            parameters.put("wrong", user1Id);

+            restNamedQuery("User.byId", "StaticUser", parameters, null);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for wrong paramter on query.", exc != null);

+        assertTrue("Wrong exception for wrong paramter on query: " + exc.getResponseStatus(), exc.getResponseStatus().equals(Status.BAD_REQUEST));

+    }

+    

+    @Test

+    public void testNamedQueryWrongNumberOfParameters(){

+        RestCallFailedException exc = null;

+        try{

+            Map<String, Object> parameters = new HashMap<String, Object>();

+            parameters.put("id", user1Id);

+            restNamedQuery("User.byNameOrId", "StaticUser", parameters, null);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for wrong numbers of paramters on query.", exc != null);

+        assertTrue("Wrong exception for wrong numbers of paramters on query: " + exc.getResponseStatus(), exc.getResponseStatus().equals(Status.BAD_REQUEST));

+    }

+    

+    @Test

+    public void testNamedQueryNoResults(){

+        Map<String, Object> parameters = new HashMap<String, Object>();

+        parameters.put("id", 0);

+        List<StaticUser> users = (List<StaticUser>)restNamedQuery("User.byId", "StaticUser", parameters, null);

+        assertTrue("Incorrect Number of users found.", users.size() == 0);

+    }

+    

+    @Test

+    public void testNonExistantNamedQuery(){

+        RestCallFailedException exc = null;

+        try{

+            Map<String, Object> parameters = new HashMap<String, Object>();

+            parameters.put("id", user1Id);

+            restNamedQuery("User.nonExistant", "StaticUser", parameters, null);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for non existant query.", exc != null);

+        assertTrue("Wrong exception for nonExistantQuery " + exc.getResponseStatus(), exc.getResponseStatus().equals(Status.BAD_REQUEST));

+    }

+    

+    @Test

+    public void testNonExistantPersistenceUnitNamedQuery(){

+        RestCallFailedException exc = null;

+        try{

+            Map<String, Object> parameters = new HashMap<String, Object>();

+            parameters.put("id", user1Id);

+            restNamedQuery("User.all", "StatisUser", "nonExistant", parameters, null, MediaType.APPLICATION_JSON_TYPE);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for query on non-existant persistence unit.", exc != null);

+        assertTrue("Wrong exception for  query on non-existant persistence unit. " + exc.getResponseStatus(), exc.getResponseStatus().equals(Status.NOT_FOUND));

+    }

+    

+    @Test

+    public void testNamedQueryHint(){

+        // load the cache

+        List<StaticUser> users = (List<StaticUser>)restNamedQuery("User.all", "StaticUser", null, null);

+        assertTrue("Incorrect Number of users found.", users.size() == 3);

+        StaticUser user1 = users.get(0);

+        String oldName = user1.getName();

+        user1.setName("Changed");

+        dbUpdate(user1);

+        Map<String, String> hints = new HashMap<String, String>();

+        hints.put(QueryHints.REFRESH, "true");

+        users = (List<StaticUser>)restNamedQuery("User.all", "StaticUser", null, hints);

+        for (StaticUser user: users){

+            if (user.getId() == user1.getId()){

+                assertTrue("User was not refreshed", user.getName().equals(user1.getName()));

+            }

+        }

+        user1.setName(oldName);

+        dbUpdate(user1);        

+        // refresh cache

+        hints = new HashMap<String, String>();

+        hints.put(QueryHints.REFRESH, "true");

+        users = (List<StaticUser>)restNamedQuery("User.all", "StaticUser", null, hints);

+    }

+    

+    @Test

+    public void testNamedQueryParameterHint(){

+        Map<String, Object> parameters = new HashMap<String, Object>();

+        parameters.put("id", user1Id);

+        // load the cache

+        List<StaticUser> users = (List<StaticUser>)restNamedQuery("User.byId", "StaticUser", parameters, null);

+        assertTrue("Incorrect Number of users found.", users.size() == 1);

+        assertTrue("Wrong user returned", users.get(0).getId() == user1Id);

+        StaticUser user1 = users.get(0);

+        String oldName = user1.getName();

+        user1.setName("Changed2");

+        dbUpdate(user1);

+        Map<String, String> hints = new HashMap<String, String>();

+        hints.put(QueryHints.REFRESH, "true");

+        users = (List<StaticUser>)restNamedQuery("User.byId", "StaticUser", parameters, hints);

+        assertTrue("User was not refreshed", users.get(0).getName().equals(user1.getName()));

+        user1.setName(oldName);

+        dbUpdate(user1);  

+        

+        // refresh cache

+        hints = new HashMap<String, String>();

+        hints.put(QueryHints.REFRESH, "true");

+        users = (List<StaticUser>)restNamedQuery("User.all", "StaticUser", null, hints);

+    }

+    

+    @Test

+    public void testNamedQuerySingleResult(){

+        Map<String, Object> parameters = new HashMap<String, Object>();

+        parameters.put("id", user1Id);

+        StaticUser user = (StaticUser)restNamedSingleResultQuery("User.byId", "StaticUser", DEFAULT_PU, parameters, null, MediaType.APPLICATION_JSON_TYPE);

+        assertTrue("user was not returned", user != null);

+        assertTrue("incorrect user returned", user.getName().equals("user1"));

+    }

+    

+    @Test

+    public void testNamedQuerySingleResultNoResult(){

+        Map<String, Object> parameters = new HashMap<String, Object>();

+        parameters.put("id", 0);

+        RestCallFailedException exc = null;

+        try{

+            StaticUser user = (StaticUser)restNamedSingleResultQuery("User.byId", "StaticUser", DEFAULT_PU, parameters, null, MediaType.APPLICATION_JSON_TYPE);

+            assertTrue("user shoudl not have been returned", user == null);

+        } catch (RestCallFailedException e){

+            exc = e;

+        }

+        assertTrue("No exception thrown for query with no result.", exc != null);

+        assertTrue("Wrong exception for for query with no result " + exc.getResponseStatus(), exc.getResponseStatus().equals(Status.NOT_FOUND));

+

+    }

+    

+    @Test

+    public void testUpdateQuery(){

+        Map<String, Object> parameters = new HashMap<String, Object>();

+        parameters.put("id", user1Id);

+        parameters.put("name", "newName");

+        Object result = restUpdateQuery("User.updateName", "StaticUser", DEFAULT_PU, parameters, null);

+        assertTrue(result.equals("1"));

+        StaticUser user1 = dbRead(user1Id, StaticUser.class);

+        assertTrue(user1.getName().equals("newName"));

+        dbUpdate(user1());

+    }

+    

+    public static <T> T dbRead(Object id, Class<T> resultClass){

+        context.getEmf().getCache().evictAll();

+        EntityManager em = context.getEmf().createEntityManager();

+        return em.find(resultClass, id);

+    }

+    

+    public static void dbUpdate(Object object){

+        EntityManager em = context.getEmf().createEntityManager();

+        em.getTransaction().begin();

+        em.merge(object);

+        em.getTransaction().commit();

+    }

+    

+    public static <T> T restCreate(Object object, String type, Class<T> resultClass) throws RestCallFailedException {

+        return restCreate(object, type, resultClass, DEFAULT_PU, MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE);

+    }

+    

+    public static <T> T restCreate(Object object, String type, Class<T> resultClass, String persistenceUnit, MediaType inputMediaType, MediaType outputMediaType) throws RestCallFailedException {

+        WebResource webResource = client.resource(SERVER_URI + persistenceUnit + "/entity/" + type);

         ByteArrayOutputStream os = new ByteArrayOutputStream();

         try{

-            context.marshallEntity(bid, MediaType.APPLICATION_JSON_TYPE, os);

+            context.marshallEntity(object, inputMediaType, os);       

+        } catch (JAXBException e){

+            fail("Exception thrown unmarshalling: " + e);

+        }

+        ClientResponse response = webResource.type(inputMediaType).accept(outputMediaType).put(ClientResponse.class, os.toString());

+        Status status = response.getClientResponseStatus();

+        if (status != Status.CREATED){

+            throw new RestCallFailedException(status);

+        }

+        String result = response.getEntity(String.class);

+        T resultObject = null;

+        try {

+            resultObject = (T)context.unmarshalEntity(type, null, outputMediaType, new ByteArrayInputStream(result.getBytes()));

+        } catch (JAXBException e){

+            fail("Exception thrown unmarshalling: " + e);

+        }

+        return resultObject;

+    }

+    public static <T> void restDelete(Object id, String type, Class<T> resultClass) throws RestCallFailedException {

+        restDelete(id, type, resultClass, DEFAULT_PU);

+    }

+    

+    public static <T> void restDelete(Object id, String type, Class<T> resultClass, String persistenceUnit) throws RestCallFailedException {

+        WebResource webResource = client.resource(SERVER_URI + persistenceUnit + "/entity/" + type + "/" + id);

+        ClientResponse response = webResource.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).delete(ClientResponse.class);

+        Status status = response.getClientResponseStatus();

+        if (status != Status.OK){

+            throw new RestCallFailedException(status);

+        }

+    }

+    

+    public static Object restNamedQuery(String queryName, String returnType, Map<String, Object> parameters, Map<String, String> hints){

+        return restNamedQuery(queryName, returnType, DEFAULT_PU, parameters, hints, MediaType.APPLICATION_JSON_TYPE);

+    }

+    

+    public static Object restNamedQuery(String queryName, String returnType, String persistenceUnit, Map<String, Object> parameters, Map<String, String> hints, MediaType outputMediaType){

+        StringBuffer resourceURL = new StringBuffer();

+        resourceURL.append(SERVER_URI + persistenceUnit + "/query/" + queryName);

+        appendParametersAndHints(resourceURL, parameters, hints);

+        WebResource webResource = client.resource(resourceURL.toString());

+        ClientResponse response = webResource.accept(outputMediaType).get(ClientResponse.class);

+        Status status = response.getClientResponseStatus();

+        if (status != Status.OK){

+            throw new RestCallFailedException(status);

+        }

+        String result = response.getEntity(String.class);

+        try {

+            return context.unmarshalEntity(returnType, null, outputMediaType, new ByteArrayInputStream(result.getBytes()));

+        } catch (JAXBException e){

+            fail("Exception thrown unmarshalling: " + e);

+        }

+        return null;

+    }

+    

+    public static Object restNamedSingleResultQuery(String queryName, String returnType, String persistenceUnit, Map<String, Object> parameters, Map<String, String> hints, MediaType outputMediaType){

+        StringBuffer resourceURL = new StringBuffer();

+        resourceURL.append(SERVER_URI + persistenceUnit + "/singleResultQuery/" + queryName);

+        appendParametersAndHints(resourceURL, parameters, hints);

+        

+        WebResource webResource = client.resource(resourceURL.toString());

+        ClientResponse response = webResource.accept(outputMediaType).get(ClientResponse.class);

+        Status status = response.getClientResponseStatus();

+        if (status != Status.OK){

+            throw new RestCallFailedException(status);

+        }

+        String result = response.getEntity(String.class);

+        try {

+            return context.unmarshalEntity(returnType, null, outputMediaType, new ByteArrayInputStream(result.getBytes()));

+        } catch (JAXBException e){

+            fail("Exception thrown unmarshalling: " + e);

+        }

+        return null;

+    }

+    

+    public static Object restUpdateQuery(String queryName, String returnType, String persistenceUnit, Map<String, Object> parameters, Map<String, String> hints){

+        StringBuffer resourceURL = new StringBuffer();

+        resourceURL.append(SERVER_URI + persistenceUnit + "/query/" + queryName);

+        appendParametersAndHints(resourceURL, parameters, hints);

+        

+        WebResource webResource = client.resource(resourceURL.toString());

+        ClientResponse response = webResource.post(ClientResponse.class);

+        Status status = response.getClientResponseStatus();

+        if (status != Status.OK){

+            throw new RestCallFailedException(status);

+        }

+        return response.getEntity(String.class);

+    }

+    

+    private static void appendParametersAndHints(StringBuffer resourceURL, Map<String, Object> parameters, Map<String, String> hints){

+        if (parameters != null && !parameters.isEmpty()){

+            for (String key: parameters.keySet()){

+                resourceURL.append(";" + key + "=" + parameters.get(key));

+            }

+        }

+        if (hints != null && !hints.isEmpty()){

+            boolean firstElement = true;

+                

+            for (String key: hints.keySet()){

+                if (firstElement){

+                    resourceURL.append("?"); 

+                } else {

+                    resourceURL.append("&");

+                }

+                resourceURL.append(key + "=" + hints.get(key));

+            }

+        }

+    }

+    

+    public static <T> T restRead(Object id, String type, Class<T> resultClass) throws RestCallFailedException {

+        return restRead(id, type, resultClass, DEFAULT_PU, MediaType.APPLICATION_JSON_TYPE);

+    }

+    

+    public static <T> T restRead(Object id, String type, Class<T> resultClass, String persistenceUnit, MediaType outputMediaType) throws RestCallFailedException {

+        WebResource webResource = client.resource(SERVER_URI + persistenceUnit + "/entity/" + type + "/" + id);

+        ClientResponse response = webResource.accept(outputMediaType).get(ClientResponse.class);

+        Status status = response.getClientResponseStatus();

+        if (status != Status.OK){

+            throw new RestCallFailedException(status);

+        }

+        String result = response.getEntity(String.class);

+        T resultObject = null;

+        try {

+            resultObject = (T)context.unmarshalEntity(type, null, outputMediaType, new ByteArrayInputStream(result.getBytes()));

+        } catch (JAXBException e){

+            fail("Exception thrown unmarshalling: " + e);

+        }

+        return resultObject;

+    }

+    

+    

+    public static <T> T restUpdate(Object object, String type, Class<T> resultClass) throws RestCallFailedException {

+        return restUpdate(object, type, resultClass, DEFAULT_PU, MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON_TYPE);

+    }

+    

+    public static <T> T restUpdate(Object object, String type, Class<T> resultClass, String persistenceUnit, MediaType inputMediaType, MediaType outputMediaType) throws RestCallFailedException {

+

+        WebResource webResource = client.resource(SERVER_URI + persistenceUnit + "/entity/" + type);

+        ByteArrayOutputStream os = new ByteArrayOutputStream();

+        try{

+            context.marshallEntity(object, inputMediaType, os);

         

         } catch (JAXBException e){

             fail("Exception thrown unmarshalling: " + e);

         }

-        result = webResource.type(MediaType.APPLICATION_JSON).accept(MediaType.APPLICATION_JSON).post(String.class, os.toString());

+        ClientResponse response = webResource.type(inputMediaType).accept(outputMediaType).post(ClientResponse.class, os.toString());

+        Status status = response.getClientResponseStatus();

+        if (status != Status.OK){

+            throw new RestCallFailedException(status);

+        }

+        String result = response.getEntity(String.class);

+        

+        T resultObject = null;

         try {

-            bid = (StaticBid)context.unmarshalEntity("StaticBid", null, MediaType.APPLICATION_JSON_TYPE, new ByteArrayInputStream(result.getBytes()));

+            resultObject = (T)context.unmarshalEntity(type, null, outputMediaType, new ByteArrayInputStream(result.getBytes()));

         } catch (JAXBException e){

             fail("Exception thrown unmarshalling: " + e);

         }

-        assertTrue("Wrong big retrieved.", bid.getBid() == 120);

-        assertTrue("No user for Bid", bid.getUser() != null);

-        assertTrue("No auction for Bid", bid.getAuction() != null);

+        return resultObject;

     }

     

     public static Object unmarshall(String result, String mediaType, Class expectedResultClass){

@@ -213,18 +817,21 @@
     

     public static StaticUser user1(){

         StaticUser user = new StaticUser();

+        user.setId(11);

         user.setName("user1");

         return user;

     }

     

     public static StaticUser user2(){

         StaticUser user = new StaticUser();

+        user.setId(22);

         user.setName("user2");

         return user;

     }

     

     public static StaticUser user3(){

         StaticUser user = new StaticUser();

+        user.setId(33);

         user.setName("user3");

         return user;

     }

diff --git a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/service/TestService.java b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/service/TestService.java
index bef6832..188609e 100644
--- a/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/service/TestService.java
+++ b/JPA-RS/org.eclipse.persistence.jpars.test/src/org/eclipse/persistence/jpars/test/service/TestService.java
@@ -134,7 +134,7 @@
         entities.add(entity);

         entities.add(entity2);

 

-        StreamingOutput output = service.update("auction", "User", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo(), TestService.serializeListToStream(entities, context, MediaType.APPLICATION_JSON_TYPE));

+        StreamingOutput output = (StreamingOutput)service.update("auction", "User", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo(), TestService.serializeListToStream(entities, context, MediaType.APPLICATION_JSON_TYPE)).getEntity();

 

         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

         try{

@@ -187,7 +187,7 @@
         entities.add(entity);

         entities.add(entity2);

 

-        StreamingOutput output = service.update("phonebook", "Person", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo(), serializeListToStream(entities, context, MediaType.APPLICATION_JSON_TYPE));

+        StreamingOutput output = (StreamingOutput)service.update("phonebook", "Person", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo(), serializeListToStream(entities, context, MediaType.APPLICATION_JSON_TYPE)).getEntity();

 

         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

         try{

@@ -293,7 +293,7 @@
         List<String> mediaTypes = new ArrayList<String>();

         mediaTypes.add(MediaType.APPLICATION_JSON);

         TestURIInfo ui = new TestURIInfo();

-        StreamingOutput output = service.namedQuery("auction", "Auction.all", headers, ui);

+        StreamingOutput output = (StreamingOutput)service.namedQuery("auction", "Auction.all", headers, ui).getEntity();

      

         ByteArrayOutputStream outputStream = new ByteArrayOutputStream();

         try{

@@ -328,7 +328,7 @@
         mediaTypes.add(MediaType.APPLICATION_JSON);

         TestURIInfo ui = new TestURIInfo();

         ui.addMatrixParameter("name", "Computer");

-        StreamingOutput output = service.namedQuerySingleResult("auction", "Auction.forName", headers, ui);

+        StreamingOutput output = (StreamingOutput)service.namedQuerySingleResult("auction", "Auction.forName", headers, ui).getEntity();

         

         String resultString = stringifyResults(output);

         

@@ -352,7 +352,7 @@
 

         TestURIInfo ui = new TestURIInfo();

         ui.addMatrixParameter("name", "Computer");

-        StreamingOutput output = service.update("auction", "Auction", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo(), serializeToStream(entity1, context, MediaType.APPLICATION_JSON_TYPE));

+        StreamingOutput output = (StreamingOutput)service.update("auction", "Auction", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo(), serializeToStream(entity1, context, MediaType.APPLICATION_JSON_TYPE)).getEntity();

 

         String resultString = stringifyResults(output);

         

@@ -364,7 +364,12 @@
     public void testMetadataQuery(){

         Service service = new Service();

         service.setPersistenceFactory(factory);

-        StreamingOutput output = (StreamingOutput)service.getContexts(generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo()).getEntity();

+        StreamingOutput output = null;

+        try{

+            output = (StreamingOutput)service.getContexts(generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo()).getEntity();

+        } catch (JAXBException e){

+            fail("Exception: " + e);

+        }

         String result = stringifyResults(output);

         assertTrue("auction was not in the results", result.contains("auction"));

         assertTrue("phonebook was not in the results", result.contains("phonebook"));

@@ -447,6 +452,7 @@
         PersistenceContext context = factory.getPersistenceContext("auction-static");

         StaticUser user = new StaticUser();

         user.setName("Wes");

+        user.setId(7);

         StaticAddress address = new StaticAddress();

         address.setCity("Ottawa");

         address.setPostalCode("a1a1a1");

@@ -489,8 +495,12 @@
     public void testMetadata(){

         Service service = new Service();

         service.setPersistenceFactory(factory);

-        Object result = service.getContexts(generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo());

-        

+        Object result = null;

+        try{

+            result = service.getContexts(generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo());

+        } catch (JAXBException e){

+            fail("Exception: " + e);

+        }

         result = service.getTypes("auction", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo());

 

         result = service.getDescriptorMetadata("auction", "Bid", generateHTTPHeader(MediaType.APPLICATION_JSON_TYPE, MediaType.APPLICATION_JSON), new TestURIInfo());

diff --git a/JPA-RS/org.eclipse.persistence.jpars/META-INF/MANIFEST.MF b/JPA-RS/org.eclipse.persistence.jpars/META-INF/MANIFEST.MF
index 9de16c3..5e8564c 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/META-INF/MANIFEST.MF
+++ b/JPA-RS/org.eclipse.persistence.jpars/META-INF/MANIFEST.MF
@@ -16,4 +16,5 @@
  javax.persistence.metamodel;version="2.0.0",
  javax.persistence.spi;version="2.0.0",
  javax.ws.rs,
- javax.ws.rs.core
+ javax.ws.rs.core,
+ javax.ws.rs.ext
diff --git a/JPA-RS/org.eclipse.persistence.jpars/dist/jpars.jar b/JPA-RS/org.eclipse.persistence.jpars/dist/jpars.jar
index 9fc85ad..8125429 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/dist/jpars.jar
+++ b/JPA-RS/org.eclipse.persistence.jpars/dist/jpars.jar
Binary files differ
diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
index da3dbbb..ccdb3c0 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/PersistenceContext.java
@@ -43,7 +43,6 @@
 import javax.xml.stream.XMLStreamWriter;

 import javax.xml.transform.stream.StreamSource;

 

-import org.eclipse.persistence.config.PersistenceUnitProperties;

 import org.eclipse.persistence.descriptors.ClassDescriptor;

 import org.eclipse.persistence.dynamic.DynamicEntity;

 import org.eclipse.persistence.dynamic.DynamicType;

@@ -305,7 +304,9 @@
         try {

             transaction.beginTransaction(em);

             Object entity = em.find(getClass(type), id);

-            em.remove(entity);

+            if (entity != null){

+                em.remove(entity);          

+            }

             transaction.commitTransaction(em);

         } finally {

             em.close();

@@ -540,9 +541,6 @@
             } else {

                 return query.getResultList();

             }

-        } catch (Exception e){

-            // TODO proper exception

-            throw new RuntimeException("Error running query " + name, e);

         } finally {

             em.close();

         }

@@ -626,7 +624,6 @@
         Marshaller marshaller = getJAXBContext().createMarshaller();

         marshaller.setProperty(MEDIA_TYPE, mediaType.toString());

         marshaller.setProperty(org.eclipse.persistence.jaxb.JAXBContext.JSON_INCLUDE_ROOT, false);

-System.out.println("--- marshallEntity - " + object + " baseURI" + getBaseURI());

         marshaller.setAdapter(new LinkAdapter(getBaseURI().toString(), this));

         marshaller.setListener(new Marshaller.Listener() {

             @Override

@@ -656,10 +653,8 @@
             } catch (Exception e){

                 e.printStackTrace();

                 throw new RuntimeException(e);

-            }

-           

-        } else {

-        

+            }          

+        } else {       

             marshaller.marshal(object, output);      

         }

     }

diff --git a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/Service.java b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/Service.java
index 9cd216c..5478121 100644
--- a/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/Service.java
+++ b/JPA-RS/org.eclipse.persistence.jpars/src/org/eclipse/persistence/jpa/rs/Service.java
@@ -15,11 +15,12 @@
 import static org.eclipse.persistence.jaxb.JAXBContext.MEDIA_TYPE;

 import static org.eclipse.persistence.jpa.rs.util.StreamingOutputMarshaller.mediaType;

 

-import java.io.CharArrayReader;

+import java.io.IOException;

 import java.io.InputStream;

 import java.io.StringWriter;

 import java.lang.reflect.InvocationTargetException;

 import java.lang.reflect.Method;

+import java.net.MalformedURLException;

 import java.net.URI;

 import java.net.URL;

 import java.util.ArrayList;

@@ -29,7 +30,6 @@
 import java.util.Map;

 import java.util.Map.Entry;

 import java.util.Set;

-import java.util.logging.Level;

 import java.util.logging.Logger;

 

 import javax.annotation.PreDestroy;

@@ -55,7 +55,6 @@
 import javax.ws.rs.core.Response;

 import javax.ws.rs.core.Response.ResponseBuilder;

 import javax.ws.rs.core.Response.Status;

-import javax.ws.rs.core.StreamingOutput;

 import javax.ws.rs.core.UriInfo;

 import javax.xml.bind.JAXBException;

 import javax.xml.bind.Marshaller;

@@ -84,6 +83,7 @@
 import org.eclipse.persistence.mappings.CollectionMapping;

 import org.eclipse.persistence.mappings.DatabaseMapping;

 import org.eclipse.persistence.mappings.ForeignReferenceMapping;

+import org.eclipse.persistence.mappings.foundation.AbstractDirectMapping;

 import org.eclipse.persistence.queries.DatabaseQuery;

 

 import com.sun.jersey.core.spi.factory.ResponseBuilderImpl;

@@ -117,25 +117,20 @@
    @Consumes({ MediaType.WILDCARD})

    public Response start(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, InputStream in){

        ResponseBuilder rb = new ResponseBuilderImpl();

-       try{

-           factory.setMetadataStore(new DatabaseMetadataStore());

-           List<String> datasourceValues = hh.getRequestHeader("datasourceName");

-           Map<String, Object> properties = new HashMap<String, Object>();

-           if (datasourceValues != null && datasourceValues.size() > 0){

-               properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, datasourceValues.get(0));

-           }

-           factory.getMetadataStore().setProperties(properties);

-       } catch (Exception e){

-           rb.status(Status.NOT_FOUND);

-           return rb.build();

+       factory.setMetadataStore(new DatabaseMetadataStore());

+       List<String> datasourceValues = hh.getRequestHeader("datasourceName");

+       Map<String, Object> properties = new HashMap<String, Object>();

+       if (datasourceValues != null && datasourceValues.size() > 0){

+           properties.put(PersistenceUnitProperties.NON_JTA_DATASOURCE, datasourceValues.get(0));

        }

+       factory.getMetadataStore().setProperties(properties);

        rb.status(Status.CREATED);

        return rb.build();

    }

    

    @GET

    @Path("/")

-   public Response getContexts(@Context HttpHeaders hh, @Context UriInfo uriInfo) {

+   public Response getContexts(@Context HttpHeaders hh, @Context UriInfo uriInfo) throws JAXBException {

        ResponseBuilder rb = new ResponseBuilderImpl();

        Set<String> contexts = factory.getPersistenceContextNames();

        Iterator<String> contextIterator = contexts.iterator();

@@ -146,12 +141,7 @@
            links.add(new Link(context, mediaType, "\"href\": \"" + uriInfo.getBaseUri() + context + "/metadata\""));

        }

        String result = null;

-       try {

-           result = marshallMetadata(links, mediaType);

-       } catch (JAXBException e){

-           rb.status(Status.INTERNAL_SERVER_ERROR);

-           return rb.build();

-       }

+       result = marshallMetadata(links, mediaType);

        rb.status(Status.OK);

        rb.entity(new StreamingOutputMarshaller(null, result, hh.getAcceptableMediaTypes()));

        return rb.build();

@@ -161,79 +151,58 @@
    @POST

    @Path("/")

    @Produces(MediaType.WILDCARD)

-   public Response callSessionBean(@Context HttpHeaders hh, @Context UriInfo ui, InputStream is) {

+   public Response callSessionBean(@Context HttpHeaders hh, @Context UriInfo ui, InputStream is) throws JAXBException, ClassNotFoundException, NamingException, NoSuchMethodException, InvocationTargetException, IllegalAccessException {

        ResponseBuilder rb = new ResponseBuilderImpl();

        SessionBeanCall call = null;

-       try {

-           call = unmarshallSessionBeanCall(is);

+       call = unmarshallSessionBeanCall(is);

 

-           String jndiName = call.getJndiName();

-           System.out.println("Lookup: " + jndiName);

-           javax.naming.Context ctx = new InitialContext();

-           System.out.println("Got context");

-           Object ans=ctx.lookup(jndiName);  

-           System.out.println("Got bean " + ans);

-           

-           PersistenceContext context = null;

-           if (call.getContext() != null){

-               context = factory.getPersistenceContext(call.getContext());

-           }

-           

-           Class[] parameters = new Class[call.getParameters().size()];

-           Object[] args = new Object[call.getParameters().size()];

-           int i = 0;

-           for (Parameter param: call.getParameters()){

-               System.out.println("Got paramter " + param.getValue());

-               Class parameterClass = null;

-               Object parameterValue = null;

-               if (context != null){

-                   parameterClass = context.getClass(param.getTypeName());

-               }

-               if (parameterClass != null){

-                   parameterValue = context.unmarshalEntity(param.getTypeName(), null, StreamingOutputMarshaller.mediaType(hh.getAcceptableMediaTypes()), is);

-               } else {

-                   parameterClass = Thread.currentThread().getContextClassLoader().loadClass(param.getTypeName());

-                   parameterValue = ConversionManager.getDefaultManager().convertObject(param.getValue(), parameterClass);

-               }

-               parameters[i] = parameterClass;

-               args[i] = parameterValue;

-               i++;

-           }

-           Method method = ans.getClass().getMethod(call.getMethodName(), parameters);

-           Object returnValue = method.invoke(ans, args);

-           rb.status(Status.OK);

-           rb.entity(new StreamingOutputMarshaller(null, returnValue, hh.getAcceptableMediaTypes()));

-           return rb.build();

-       } catch (JAXBException e){

-           logger.log(Level.SEVERE, "JAXBException. ", e);

-           rb.status(Status.INTERNAL_SERVER_ERROR);

-           return rb.build();

-       } catch (NamingException e){

-           logger.log(Level.SEVERE, "JNDIException ", e);

-           rb.status(Status.INTERNAL_SERVER_ERROR);

-           return rb.build();

-       } catch (ClassNotFoundException e){

-           logger.log(Level.SEVERE, "ClassNotFoundException. ", e);

-           rb.status(Status.INTERNAL_SERVER_ERROR);

-           return rb.build();

-       } catch (NoSuchMethodException e){

-           logger.log(Level.SEVERE, "NoSuchMethodException. ", e);

-           rb.status(Status.INTERNAL_SERVER_ERROR);

-           return rb.build();

-       } catch (IllegalAccessException e){

-           logger.log(Level.SEVERE, "IllegalAccessException. ", e);

-           rb.status(Status.INTERNAL_SERVER_ERROR);

-           return rb.build();

-       } catch (InvocationTargetException e){

-           logger.log(Level.SEVERE, "InvocationTargetException. ", e);

-           rb.status(Status.INTERNAL_SERVER_ERROR);

+       String jndiName = call.getJndiName();

+       javax.naming.Context ctx = new InitialContext();

+       Object ans=ctx.lookup(jndiName);  

+       if (ans == null){

+           rb.status(Status.NOT_FOUND);

            return rb.build();

        }

+           

+       PersistenceContext context = null;

+       if (call.getContext() != null){

+           context = factory.getPersistenceContext(call.getContext());

+           if (context == null){

+               rb.status(Status.NOT_FOUND);

+               return rb.build();

+           }

+       }

+           

+       Class[] parameters = new Class[call.getParameters().size()];

+       Object[] args = new Object[call.getParameters().size()];

+       int i = 0;

+       for (Parameter param: call.getParameters()){

+           System.out.println("Got paramter " + param.getValue());

+           Class parameterClass = null;

+           Object parameterValue = null;

+           if (context != null){

+               parameterClass = context.getClass(param.getTypeName());

+           }

+           if (parameterClass != null){

+               parameterValue = context.unmarshalEntity(param.getTypeName(), null, hh.getMediaType(), is);

+           } else {

+               parameterClass = Thread.currentThread().getContextClassLoader().loadClass(param.getTypeName());

+               parameterValue = ConversionManager.getDefaultManager().convertObject(param.getValue(), parameterClass);

+           }

+           parameters[i] = parameterClass;

+           args[i] = parameterValue;

+           i++;

+       }

+       Method method = ans.getClass().getMethod(call.getMethodName(), parameters);

+       Object returnValue = method.invoke(ans, args);

+       rb.status(Status.OK);

+       rb.entity(new StreamingOutputMarshaller(null, returnValue, hh.getAcceptableMediaTypes()));

+       return rb.build();

    }

    

     @PUT

     @Path("{context}")

-    public Response bootstrap(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in){

+    public Response bootstrap(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) throws IOException, MalformedURLException{

         ResponseBuilder rb = new ResponseBuilderImpl();

         String urlString = getSingleHeader("persistenceXmlURL", hh);

 

@@ -244,16 +213,11 @@
             replace = Boolean.getBoolean(replaceValues.get(0));

         }

         Map<String, Object> properties = new HashMap<String, Object>();

-        try{

-            if (urlString != null){

-                URL url = new URL(urlString);

-                persistenceContext = factory.bootstrapPersistenceContext(persistenceUnit, url, properties, replace);

-            } else {

-                persistenceContext = factory.bootstrapPersistenceContext(persistenceUnit, in, properties, replace);

-            }

-       } catch (Exception e){

-            e.printStackTrace();

-            rb.status(Status.NOT_FOUND);

+        if (urlString != null){

+            URL url = new URL(urlString);

+            persistenceContext = factory.bootstrapPersistenceContext(persistenceUnit, url, properties, replace);

+        } else {

+            persistenceContext = factory.bootstrapPersistenceContext(persistenceUnit, in, properties, replace);

         }

         if (persistenceContext != null){

             persistenceContext.setBaseURI(uriInfo.getBaseUri());

@@ -307,7 +271,6 @@
     @Path("{context}/subscribe/{name}")

     public Response subscribe(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context UriInfo ui) {

         ResponseBuilder rb = new ResponseBuilderImpl();

-        System.out.println("Subscribe " + name);

         PersistenceContext app = get(persistenceUnit, ui.getBaseUri());

         if (app == null){

             rb.status(Status.NOT_FOUND);

@@ -376,11 +339,16 @@
     @GET

     @Path("{context}/entity/{type}/{key}")

     public Response find(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @Context HttpHeaders hh, @Context UriInfo ui) {

+        ResponseBuilder rb = new ResponseBuilderImpl();

         PersistenceContext app = get(persistenceUnit, ui.getBaseUri());

+        if (app == null || app.getClass(type) == null){

+            rb.status(Status.NOT_FOUND);

+            return rb.build();

+        }

         Object id = IdHelper.buildId(app, type, key);

 

         Object entity = app.find(getTenantId(hh), type, id, Service.getHintMap(ui));

-        ResponseBuilder rb = new ResponseBuilderImpl();

+

         if (entity == null) {

             rb.status(Status.NOT_FOUND);

         } else {

@@ -392,17 +360,44 @@
 

     @PUT

     @Path("{context}/entity/{type}")

-    public Response create(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) {

+    public Response create(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) throws JAXBException {

         PersistenceContext app = get(persistenceUnit, uriInfo.getBaseUri());

+        ResponseBuilder rb = new ResponseBuilderImpl();

+        ClassDescriptor descriptor = app.getDescriptor(type);

+        if (app == null || descriptor == null){

+            rb.status(Status.NOT_FOUND);

+            return rb.build();

+        }

         Object entity = null;

-        try {

+        try{

             entity = app.unmarshalEntity(type, getTenantId(hh), mediaType(hh.getAcceptableMediaTypes()), in);

         } catch (JAXBException e){

-            throw new WebApplicationException(e);

+            throw e;

         }

-        app.create(getTenantId(hh), entity);

 

-        ResponseBuilder rb = new ResponseBuilderImpl();

+        // maintain itempotence on PUT by disallowing sequencing and cascade persist.

+        AbstractDirectMapping sequenceMapping = descriptor.getObjectBuilder().getSequenceMapping();

+        if (sequenceMapping != null){

+            Object value = sequenceMapping.getAttributeAccessor().getAttributeValueFromObject(entity);

+

+            if (descriptor.getObjectBuilder().isPrimaryKeyComponentInvalid(value, descriptor.getPrimaryKeyFields().indexOf(descriptor.getSequenceNumberField())) || descriptor.getSequence().shouldAlwaysOverrideExistingValue()){

+                rb.status(Status.BAD_REQUEST);

+                return rb.build();

+            }

+        }

+        for (DatabaseMapping mapping: descriptor.getObjectBuilder().getRelationshipMappings()){

+            if (mapping.isForeignReferenceMapping()){

+                if (((ForeignReferenceMapping)mapping).isCascadePersist()){

+                    Object value = mapping.getAttributeAccessor().getAttributeValueFromObject(entity);

+                    if (value != null){

+                        rb.status(Status.BAD_REQUEST);

+                        return rb.build();

+                    }

+                }

+            }

+        }

+

+        app.create(getTenantId(hh), entity);

         rb.status(Status.CREATED);

         rb.entity(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes()));

         return rb.build();

@@ -410,8 +405,13 @@
 

     @POST

     @Path("{context}/entity/{type}")

-    public StreamingOutput update(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) {

+    public Response update(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @Context HttpHeaders hh, @Context UriInfo uriInfo, InputStream in) {

         PersistenceContext app = get(persistenceUnit, uriInfo.getBaseUri());

+        ResponseBuilder rb = new ResponseBuilderImpl();

+        if (app == null || app.getClass(type) == null){

+            rb.status(Status.NOT_FOUND);

+            return rb.build();

+        }

         String tenantId = getTenantId(hh);

         MediaType contentType = mediaType(hh.getRequestHeader(HttpHeaders.CONTENT_TYPE)); 

         Object entity = null;

@@ -421,7 +421,8 @@
             throw new WebApplicationException(e);

         }

         entity = app.merge(tenantId, entity);

-        return new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes());

+        rb.entity(new StreamingOutputMarshaller(app, entity, hh.getAcceptableMediaTypes()));

+        return rb.build();

     }

 

     @DELETE

@@ -429,6 +430,10 @@
     public Response delete(@PathParam("context") String persistenceUnit, @PathParam("type") String type, @PathParam("key") String key, @Context HttpHeaders hh, @Context UriInfo ui) {

         ResponseBuilder rb = new ResponseBuilderImpl();

         PersistenceContext app = get(persistenceUnit, ui.getBaseUri());

+        if (app == null || app.getClass(type) == null){

+            rb.status(Status.NOT_FOUND);

+            return rb.build();

+        }

         String tenantId = getTenantId(hh);

         Object id = IdHelper.buildId(app, type, key);

         app.delete(tenantId, type, id);

@@ -437,40 +442,51 @@
     }

     

     @GET

-    @Path("{context}/query")

-    public StreamingOutput adhocQuery(@PathParam("context") String persistenceUnit, @Context HttpHeaders hh, @Context UriInfo ui) {

-        throw new WebApplicationException(Status.SERVICE_UNAVAILABLE);

-    }

-    

-    @GET

     @Path("{context}/query/{name}")

-    public StreamingOutput namedQuery(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {

-        long millis = System.currentTimeMillis();

-        System.out.println("Start Named Query " + name);

+    public Response namedQuery(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {

         PersistenceContext app = get(persistenceUnit, ui.getBaseUri());

+        ResponseBuilder rb = new ResponseBuilderImpl();

+        if (app == null){

+            rb.status(Status.NOT_FOUND);

+            return rb.build();

+        }

         Object result = app.query(name, Service.getParameterMap(ui), Service.getHintMap(ui), false, false);

 

-

-        System.out.println("Named Query " + name + " Marshalling. time: " + (System.currentTimeMillis() - millis));

-        return new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes());

+        rb.status(Status.OK);

+        rb.entity(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes()));

+        return rb.build();

     }

     

     @POST

     @Path("{context}/query/{name}")

-    @Produces({ MediaType.APPLICATION_OCTET_STREAM })

-    public StreamingOutput namedQueryUpdate(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {

+    @Produces({ MediaType.APPLICATION_OCTET_STREAM})

+    public Response namedQueryUpdate(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {

         PersistenceContext app = get(persistenceUnit, ui.getBaseUri());

+        ResponseBuilder rb = new ResponseBuilderImpl();

+        if (app == null){

+            rb.status(Status.NOT_FOUND);

+            return rb.build();

+        }

         Object result = app.query(name, Service.getParameterMap(ui), Service.getHintMap(ui), false, true);

-        return new StreamingOutputMarshaller(app, result.toString(), hh.getAcceptableMediaTypes());

+        rb.status(Status.OK);

+        rb.entity(new StreamingOutputMarshaller(app, result.toString(), hh.getAcceptableMediaTypes()));

+        return rb.build();

     }

     

     @GET

     @Path("{context}/singleResultQuery/{name}")

     @Produces(MediaType.WILDCARD)

-    public StreamingOutput namedQuerySingleResult(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {

+    public Response namedQuerySingleResult(@PathParam("context") String persistenceUnit, @PathParam("name") String name, @Context HttpHeaders hh, @Context UriInfo ui) {

         PersistenceContext app = get(persistenceUnit, ui.getBaseUri());

+        ResponseBuilder rb = new ResponseBuilderImpl();

+        if (app == null){

+            rb.status(Status.NOT_FOUND);

+            return rb.build();

+        }

         Object result = app.query(name, Service.getParameterMap(ui), Service.getHintMap(ui), true, false);

-        return new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes());

+        rb.status(Status.OK);

+        rb.entity(new StreamingOutputMarshaller(app, result, hh.getAcceptableMediaTypes()));

+        return rb.build();

     }

     

     protected Descriptor buildDescriptor(PersistenceContext app, String persistenceUnit, ClassDescriptor descriptor, String baseUri){