存储在数据库中手动设置的值

时间:2014-12-26 18:42:45

标签: jsf java-ee ejb persistence facade

我有一个jsf表单,其中用户键入一个int和一个字符串值,在单击Save按钮后存储在数据库中。

<h:form id="TbtestCreateForm">
    <p:inputText value="#{tbtestController.selected.name}" />
    <p:commandButton actionListener="#{tbtestController.saveNew}" value="#{myBundle.Save}" />
</h:form>

我正在使用带有façade模式的EJB,它使用AbstractController类中定义的CRUD操作,该类使用“绑定”实体类的AbstractFacade。

我需要的是硬编码/手动设置表单中的字符串值,并将其与用户通知的int值一起存储在数据库中,在同一操作中(同一个对象)

我尝试过如下操作,但没有成功:

@Named
public class MyBean implements Serializable {

@Inject
TbtestController tbtestController;

private String myName;
//GETTERS AND SETTERS

@PostConstruct
public void init() {
    myName = "some foo name";
    Tbtest myTbtest = new Tbtest();
    myTbtest.setName(myName);
    tbtestController.setSelected(myTbtest);
    tbtestController.saveNew(null); // to simulate what the savNew method do
}

我已经创建了一个可以克隆的小型netbeans项目:https://github.com/f6750699/webAppTest.git

下面是AbstractController类中定义的2个方法:

saveNew 方法:

public void saveNew(ActionEvent event) {
    String msg = ResourceBundle.getBundle("/MyBundle").getString(itemClass.getSimpleName() + "Created");
    persist(PersistAction.CREATE, msg);
    if (!isValidationFailed()) {
        items = null; // Invalidate list of items to trigger re-query.
    }
} 

持久方法:

private void persist(PersistAction persistAction, String successMessage) {
    if (selected != null) {
        this.setEmbeddableKeys();
        try {
            if (persistAction != PersistAction.DELETE) {
                this.ejbFacade.edit(selected);
            } else {
                this.ejbFacade.remove(selected);
            }
            JsfUtil.addSuccessMessage(successMessage);
        } catch (EJBException ex) {
            Throwable cause = JsfUtil.getRootCause(ex.getCause());
            if (cause != null) {
                if (cause instanceof ConstraintViolationException) {
                    ConstraintViolationException excp = (ConstraintViolationException) cause;
                    for (ConstraintViolation s : excp.getConstraintViolations()) {
                        JsfUtil.addErrorMessage(s.getMessage());
                    }
                } else {
                    String msg = cause.getLocalizedMessage();
                    if (msg.length() > 0) {
                        JsfUtil.addErrorMessage(msg);
                    } else {
                        JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/Bundle").getString("PersistenceErrorOccured"));
                    }
                }
            }
        } catch (Exception ex) {
            Logger.getLogger(this.getClass().getName()).log(Level.SEVERE, null, ex);
            JsfUtil.addErrorMessage(ex, ResourceBundle.getBundle("/MyBundle").getString("PersistenceErrorOccured"));
        }
    }
}

我真的很感激它的一些帮助,因为我已经坚持了一段时间了。

提前致谢。


保罗莫里斯解决方案

我专注于一节课,正如保罗建议的那样:

@Named
@ViewScoped
public class TbtestController extends AbstractController<Tbtest> {

@EJB
private TbtestFacade ejbFacade;

public TbtestController() {
    super(Tbtest.class); //-> there is already an invocation here, see below
}

@PostConstruct
@Override
public void init() {
    super.setFacade(ejbFacade);
//Paul Morris solution below
    myName = "some foo name";
    this.setMyName(myName);
    this.saveNew(null); // to simulate what the savNew method do
}

private String myName;

public void setMyName(String name) {
    myName = name;
}

@Override
public void saveNew(ActionEvent event) {
    this.getSelected().setName(myName);
    //super.(event); // -> invocation of a superclass constructor must be the first line in the subclass constructor, but there is already one invocation, see above. Then, I've tried to invoke the super method:
   super.saveNew(event); // but this didn't resolved, as it launches a NullPointerException, see below.
 }
}

例外:

org.jboss.weld.exceptions.WeldException: WELD-000049: Unable to invoke public void beans.TbtestController.init() on beans.TbtestController@37668b21
[...]
Caused by: java.lang.NullPointerException
at beans.TbtestController.saveNew(TbtestController.java:40)
at beans.TbtestController.init(TbtestController.java:29)
... 87 more

2 个答案:

答案 0 :(得分:1)

你说这一切都错了。将AbstractController类保留为生成。相反,修改派生类TbtestController并为硬编码字符串添加属性。然后覆盖saveNew方法,如下所示:

private String myName;

public void setMyName(String name) {
    myName = name;
}

@Override
public void saveNew(ActionEvent event) {
    this.getSelected().setName(myName);
    super.saveNew(event);    

}  

然后你的bean方法应该像这样编码:

@PostConstruct
public void init() {
    myName = "some foo name";
    tbtestController.setMyName(myName);

}

虽然我不确定你为什么要拥有MyBean类。对代码中的字符串进行硬编码,然后只需在问题顶部使用表单中的Controller saveNew方法。

更新

试试这个......

@Named
@ViewScoped
public class TbtestController extends AbstractController<Tbtest> {

    @EJB
    private TbtestFacade ejbFacade;

    public TbtestController() {
        super(Tbtest.class); //-> there is already an invocation here, see below
    }

    @PostConstruct
    @Override
    public void init() {
        super.setFacade(ejbFacade);
        //Paul Morris solution below
        myName = "";

    }

    private String myName;

    public void setMyName(String name) {
        myName = name;
    }

    public String getMyName(String name) {
        if (myName.isEmpty()) {
            myName = "Default Value";
        }
        return myName;
    }


    @Override
    public void saveNew(ActionEvent event) {
        this.getSelected().setName(this.getMyName(myName));
        super.saveNew(event); 
    }
}

答案 1 :(得分:0)

请注意:在JSF中,MVC控制器不是用户编写的代码。它们是FacesServlet和标签实现。

当人们命名JSF支持bean&#34; XXXController&#34;时,我的迂腐条纹变得模糊不清。支持bean是MODEL。动作方法和监听器是额外的MVC功能,而不是Controller方法。所有的控制器都是从View复制数据,正如我所说,JSF自动完成,无需使用用户代码。