1

XML形式のムービーでPOSTリクエストが送信されたときに正しく呼び出されるJax RSサーバーがあります。

@Resource(name = "movie")
@Path("/movie")
public class MovieResource
{

    @PersistenceContext(unitName = "movieDS")
    private EntityManager em;

    public MovieResource()
    {
        em = PersistenceProvider.createEntityManager();
    }

    @POST
    @Path("/post")
    @Consumes(
    {
        MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML
    })
    public Response createMovie(Movie movie)
    {
            if (!em.contains(newMovie))
            {
                em.merge(newMovie);
            }
        String result = "Movie created : " + movie;
        return Response.status(201).entity(movie).build();
    }
}

デバッグではエラーはまったく表示されませんが、何も永続化されません。データソースはEclipseLink上のJTAです。ここではpersistence.xmlです

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <!-- The data source should be set up in Glassfish -->
  <persistence-unit name="MovieManager" transaction-type="JTA">
    <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
    <jta-data-source>jdbc/movieDS</jta-data-source>
    <properties>
      <property name="eclipselink.logging.level" value="ALL"/>
      <property name="eclipselink.ddl-generation" value="create-tables"/>
    </properties>
  </persistence-unit>
</persistence>

EclipseLink から返されたログには、em.merge() の呼び出し中にエラーはまったく表示されません。ほとんどの場合、シーケンスの作成が関係しています。

FINEST: Execute query ValueReadQuery(name="SEQUENCE" sql="SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = #SEQ_NAME")
FINE: SELECT SEQ_COUNT FROM SEQUENCE WHERE SEQ_NAME = ?
    bind => [1 parameter bound]
FINEST: local sequencing preallocation for SEQ_GEN: objects: 50 , first: 51, last: 100
INFO: RAR7115: Unable to set ClientInfo for connection
FINEST: Connection released to connection pool [default].
FINER: TX commitTransaction, status=STATUS_ACTIVE
FINER: TX Internally committing
FINEST: local sequencing preallocation is copied to preallocation after transaction commit
FINER: external transaction has committed internally
FINEST: assign sequence to the object (51 -> net.plarz.entities.LoginInformation@91229c)

何が欠けているのか誰にも分かりますか?Movie クラスは非常にシンプルで、他のテーブルとの依存関係はありません。本当にシンプルなものが欠けていると思います。

編集 :

merge() の後に flush() を追加すると、エラーが発生します。

javax.persistence.TransactionRequiredException: 
Exception Description: No externally managed transaction is currently active for this thread
4

2 に答える 2

2

flush() を呼び出すのではなく、代わりにエンタープライズ Bean を作成する必要があります。

@Stateless
public class MovieEJB
{
  @PersistenceContext(unitName = "movieDS")
    private EntityManager em;

    @Override
    public Movie create(Movie movie) throws Exception
    {
        em.persist(movie);
        return movie;
    }

    @Override
    public void delete(Movie movie)
    {
        em.remove(em.merge(movie));
    }

    @Override
    public Movie update(Movie movie) throws Exception
    {
        return em.merge(movie);
    }
}

次に、 MovieResource クラスを次のように変更します。

@ManagedBean(name = "restController")
@SessionScoped
@Resource(name = "movie")
@Path("/movie")
public class MovieResource
{
    @EJB
    private MovieEJB movieEJB;

    public MovieResource()
    {

    }

    public MovieEJBLocal getMovieEJB()
    {
        return movieEJB;
    }

    public void setMovieEJB(MovieEJBLocal movieEJB)
    {
        this.movieEJB = movieEJB;
    }

    @POST
    @Path("/post")
    @Consumes(
    {
        MediaType.APPLICATION_JSON, MediaType.APPLICATION_XML
    })
    public Response createMovie(Movie movie)
    {
        getMovieEJB().create(movie);
        String result = "Movie created : " + movie;
        return Response.status(201).entity(movie).build();
    }
}
于 2013-09-04T10:14:25.800 に答える