Help

Controls

PermLinkWikiLink

Built with Seam

You can find the full source code for this website in the Seam package in the directory /examples/wiki. It is licensed under the LGPL.

Forum: Seam Users Forum ListTopic List
13. Aug 2008, 15:13 CET | Link

Hello i have some problems getting org.jboss.seam.web.AbstractResource to work, i also try to use a pure servlet to stream data to client with the same problem.

If i stream data from filesystem no problem with both aproaches, but when i try to stream data that is stored in database (I access data trought Hibernate JPA implementation), i can't get a entity manager, i can only solve this on pure Servlet getting a EnityManagerFactory from JNDI.

So is posible to inject the persistenceContext in AbstractResource instance or pure Servlet? I try out most of the examples and nothing work.

This is my code, running on JBoss 4.2.2GA:

components.xml

<persistence:managed-persistence-context name="entityManager" auto-create="true" persistence-unit-jndi-name="java:/axudasEntityManagerFactory" />

persistence.xml

<persistence-unit name="axudas">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <jta-data-source>java:/axudasDatasource</jta-data-source>
    <properties>
      <property name="hibernate.dialect" value="org.hibernate.dialect.Oracle9Dialect"/>
      <property name="hibernate.hbm2ddl.auto" value="validate"/>
      <property name="hibernate.show_sql" value="true"/>
      <property name="hibernate.format_sql" value="true"/>
      <property name="jboss.entity.manager.factory.jndi.name" value="java:/axudasEntityManagerFactory"/>
    </properties>
</persistence-unit>

MediaServlet.java

public class MediaServlet extends javax.servlet.http.HttpServlet implements
        javax.servlet.Servlet {
    static final long serialVersionUID = 1L;

    /*
     * (non-Java-doc)
     *
     * @see javax.servlet.http.HttpServlet#HttpServlet()
     */
    public MediaServlet() {
        super();
    }

    /*
     * (non-Java-doc)
     *
     * @see javax.servlet.http.HttpServlet#doGet(HttpServletRequest request,
     *      HttpServletResponse response)
     */
    protected void doGet(HttpServletRequest request,
            HttpServletResponse response) throws ServletException, IOException {
        response.setContentType("application/octet-stream");
        response.addHeader("Content-disposition",
                "attachment; filename=\"image.jpg\"");
        response.addHeader("Cache-Control", "no-cache");
        response.setStatus(200);
       
        // perform JNDI lookup to obtain container-managed entity manager
        EntityManager entityManager;
       
        Context initCtx;
        try {
            initCtx = new InitialContext();
            entityManager = ((EntityManagerFactory) initCtx
                    .lookup("java:axudasEntityManagerFactory")).createEntityManager();
        } catch (NamingException e) {
            throw new ServletException(e);
        }

        Prueba pb = entityManager.find(Prueba.class, 10848);

        response.flushBuffer();
        ServletOutputStream out = response.getOutputStream();

        InputStream in;
        try {
            in = pb.getData().getBinaryStream();
        } catch (SQLException e) {
            throw new ServletException(e);
        }
        // FileInputStream in = new FileInputStream(new
        // File("C:/Marcos/SIVSA/Download/eclipse-cpp-ganymede-win32.zip"));
        byte[] buff = new byte[1024];
        int nread = 0;

        while ((nread = in.read(buff)) > 0) {
            out.write(buff, 0, nread);
            out.flush();
            response.flushBuffer();
        }

        out.close();
        in.close();
    }
}

MediaResource.java

@Scope(ScopeType.APPLICATION)
@Name("myResource")
@BypassInterceptors
public class Resource extends AbstractResource {
   
    @In
    private EntityManagerFactory entityManagerFactory;

    @Override
    public String getResourcePath() {
        return "/myresource";
    }


    @Override
    public void getResource(final HttpServletRequest request, final HttpServletResponse response)
            throws ServletException, IOException {

        new ContextualHttpServletRequest(request) {
            @Override
            public void process() throws IOException, ServletException {
                response.setContentType("application/octet-stream");
                response.addHeader("Content-disposition", "attachment; filename=\"image.jpg\"");
                response.addHeader("Cache-Control", "no-cache");
                response.setStatus(200);
               
                response.flushBuffer();
                ServletOutputStream out = response.getOutputStream();
               
                EntityManager entityManager = entityManagerFactory.createEntityManager();
               
                Prueba pb = entityManager.find(Prueba.class, 10848);
               
                InputStream in;
                try {
                    in = pb.getData().getBinaryStream();
                } catch (SQLException e) {
                    throw new ServletException(e);
                }
//                FileInputStream in = new FileInputStream(new File("C:/Marcos/SIVSA/Download/eclipse-cpp-ganymede-win32.zip"));
                byte[] buff = new byte[1024];
                int nread = 0;
               
                while((nread = in.read(buff)) > 0) {
                    out.write(buff, 0, nread);
                    out.flush();
                    response.flushBuffer();
                }
               
                out.close();
                in.close();
            }
        }.run();
    }
}

So how inyect the persistence context in a clean way to AbstractResource or Servlet?

Marcos Lois

7 Replies:
13. Aug 2008, 17:17 CET | Link

I think your problem is the @BypassInterceptors in your Resource.

@Scope(ScopeType.APPLICATION)
@Name("myResource")
@BypassInterceptors
public class Resource extends AbstractResource {

Anyway there must be some other ways to accomplish this; take a look to the ContextFilter to have access to Seam compoments in your servlets.

Hope this helps :)

13. Aug 2008, 18:34 CET | Link

Yes it's mistake when i cut & paste, :).

I try without @BypassInterceptors but it don't work, i can't able to inyect entity manager or entity manager factory.

So i can get it via JNDI, so i think that will be a more reasonable and best method to do this.

From my little knowledge of Seam i think that the entityManager is socoped to conversation, so the AbstractResource class in Seam needs to be soped at aplication level, after i read this i think that i need to get a factory and create the entitymanager, so i wonder if this can not be done at container via anotation in my AbstractResource class.

So i try to inyect into Servlets with the same no success.

I also try to include this in conponents.xml.

<web:context-filter name="MediaServlet" url-pattern="/media/*" />
<web:context-filter name="seamResourceServlet" url-pattern="/seam/resource/myresource/*" />

and try to get my entitymanager instance via:

EntityManager entityManager = (EntityManager) (Component.getInstance("entityManager"));

with no success.

For the moment i continue using the JNDI aproach, so better aproach are welcome.

Regards.

13. Aug 2008, 20:26 CET | Link

I created a session to do what I need... and included that in a Component.getInstance() and worked great for me..

 
Dan Hinojosa Seam :: Groovy :: Swing Developer/Consultant/Instructor Albuquerque, NM
14. Aug 2008, 16:28 CET | Link

I solved it, so i'm a newbye in Seam.

So no injection is posible in servlets, so to get this working i need to use the org.jbos.seam.Component class to get instances of my componentes (included the entityManager), so there is a issue with this commented in http://jira.jboss.com/jira/browse/JBSEAM-957, so for solving this i need to get a transaction, and manually commit it.

When i stay at home i will post the code that work for me in both cases (Servlet and Resource).

Regards.

17. Aug 2008, 13:26 CET | Link

Hi there, as I have exactly the same issue at the very moment, could you post the code for getting the EntityManager inside the servlet? Would be great! Thx a lot!

Regards, Markus

21. Aug 2008, 12:26 CET | Link

Hi there,

thanks for the answer, but that's what I tried already. The issue I have is that the suggested way to achieve the an EntityManager by calling

EntityManager) Component.getInstance("entityManager");
returns null. Do you have any ideas why?

I thought Marcos could have helped me as it seemed he had the same issue I have. If you have any ideas, I'm thankful for every hint!

Thx, Markus