1

我使用以下内容:

  • Eclipse Java EE 朱诺
  • GlassFish 3.1.2,
  • 德比数据库,
  • JPA,
  • EclipseLink 和
  • 瓦丁 7.1.1。

此外,我是 Glassfish、DerbyDB、JPA、EcliseLink 和 Vaadin 的新手 :-) 所以如果我错了,请纠正我!


首先:请注意,有几个使用该类的示例Application,但由于这是关于 Vaadin 6,它不适合我。

我想Member使用 JPA 在 Derby DB 中持久化一个实体,但是我现在两天都在做这件事。我尝试做的是在 Vaadin 的任何地方注入一个无状态的 EJB MemberManagerBean,它有一个EntityManager来管理实体,以便在一个内部使用它来创建一个布局。MemberUICustomComponent

package de.ves.beans.entities;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Version;

@Entity
public class Member implements Serializable {

    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    protected Long id;

    @Version
    @Column(name = "OPTLOCK")
    private Long version;

    protected String name;

    public Member(){}

    // getters and setters ...

}

package de.ves.beans.mgm;

import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;

import de.ves.beans.entities.Member;

@Stateless
public class MemberManagerBean implements MemberManagerLocal {

    @PersistenceContext
    protected EntityManager entityManager;

    @Override
    public Member getMember(Long id) {
        return entityManager.find(Member.class, id);
    }

    @Override
    public Member saveMember(Member member) {
        if (member.getId() == null){
            entityManager.persist(member);
        }else{
            entityManager.merge(member);
        }
        return member;
    }

}

package de.ves.beans.mgm;

import javax.ejb.Local;
import javax.ejb.TransactionAttribute;

import de.ves.beans.entities.Member;

@TransactionAttribute
@Local
public interface MemberManagerLocal {

    public Member getMember(Long id);

    public Member saveMember(Member member);

}

package de.ves.ui;

import javax.servlet.annotation.WebServlet;

import com.vaadin.annotations.Theme;
import com.vaadin.annotations.Title;
import com.vaadin.annotations.VaadinServletConfiguration;
import com.vaadin.navigator.Navigator;
import com.vaadin.server.VaadinRequest;
import com.vaadin.server.VaadinServlet;
import com.vaadin.ui.UI;

import de.ves.beans.mgm.MemberManagerBean;
import de.ves.club.Friends;
import de.ves.club.Members;
import de.ves.club.News;
import de.ves.contact.About;
import de.ves.home.Home;
import de.ves.media.Pics;
import de.ves.media.Videos;

@SuppressWarnings("serial")
@Theme("ves")
public class VesUI extends UI {

    private Navigator navigator;

    @WebServlet(value = "/*", asyncSupported = true)
    @VaadinServletConfiguration(productionMode = false, ui = VesUI.class)
    public static class Servlet extends VaadinServlet {

    }

    @Override
    protected void init(VaadinRequest request) {
        navigator = new Navigator(this, this);

        // Home

        MainLayout main = new MainLayout();
        main.setMiddle(new Home());
        navigator.addView(Home.PATH, main); 

        // ErrorView

        navigator.setErrorView(main);

        // Subpages

        main = new MainLayout();
        main.setMiddle(new Members());
        navigator.addView(Members.PATH, main);

                    // ...

    }

}

package de.ves.club;

import com.vaadin.addon.jpacontainer.JPAContainer;
import com.vaadin.addon.jpacontainer.JPAContainerFactory;
import com.vaadin.annotations.AutoGenerated;
import com.vaadin.server.FileResource;
import com.vaadin.shared.ui.label.ContentMode;
import com.vaadin.ui.Alignment;
import com.vaadin.ui.CustomComponent;
import com.vaadin.ui.Label;
import com.vaadin.ui.Panel;
import com.vaadin.ui.VerticalLayout;

import de.ves.beans.entities.Member;

@SuppressWarnings("serial")
public class Members extends CustomComponent {


            // Components and stuff...


    public Members() {
        buildMainLayout();
        setCompositionRoot(mainLayout);

        pnl_root.setSizeFull();

        // Several inits...

                    // This is where I want to read/write from/into the DB.
                    // This is not possible since I can't access the 
                    // MemberManagerBean. The following code shows my approach
                    // concering with a JPAContainer.

        JPAContainer<Member> members = JPAContainerFactory.make(Member.class, "vesPersistence");
        Member m = new Member();
        members.addEntity(m);

    }

    @AutoGenerated
    private VerticalLayout buildMainLayout() {
        // ...
    }

            // ...

}

<?xml version="1.0" encoding="UTF-8"?>
<persistence 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"
    version="2.0">
    <persistence-unit name="vesPersistence">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <class>de.ves.beans.entities.Member</class>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <properties>
            <property name="eclipselink.target-database" value="Derby" />
            <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.ClientDriver" />
            <property name="javax.persistence.jdbc.url" value="jdbc:derby://localhost:1527/ves;create=true" />
            <property name="javax.persistence.jdbc.user" value="admin" />
            <property name="javax.persistence.jdbc.password" value="..." />
            <property name="eclipselink.ddl-generation" value="drop-and-create-tables" />
            <property name="eclipselink.logging.level" value="INFO" />
        </properties>
    </persistence-unit>
</persistence>

我的第一种方法是将 EJB 注入CustomComponent...

    @EJB
    private MemberManagerBean memberManager;

...但这会导致NullPointerException.

我读到注入仅在Servlet. (这是正确的吗?)


现在,问题在于,与常见的 DWP 不同,在 Vaadin 项目(在 MY Vaadin 项目中)只有Servlet一个UI. 应用程序内部的导航是通过 a 进行的Navigator,其他Servlets的都是不必要的。尽管静态注射Servlet对我来说是错误的,但我尝试了这种方法。再次,NullPointerException.


第三种方法:使用 a JPAContainer,如vaadin.com 上所述。这几乎可以正常工作,但触发了ServletException. 请参阅类中的代码Members

它触发了以下内容:

javax.servlet.ServletException: com.vaadin.server.ServiceException: java.lang.IllegalStateException: 异常描述:在使用 JTA 时无法使用 EntityTransaction。

我无法解释为什么会出现这种情况。


我最后的方法是关注这个论坛帖子,但它也导致了一个NullPointerException. 此外,我真的不想使用它,因为它似乎是一种解决方法。


我很想使用JPAContainer,但在 Vaadin 中使用 JPA 的一种常见的常规方式确实会有所帮助。

而已。你能帮我吗 :-) 在此先感谢您的帮助!

4

0 回答 0