value="#{nnController.nnDescr.descr}":目标无法到达,'null' 返回 null
value="#{nnController.nnDescr.descr}": Target Unreachable, 'null' returned null
我试着在这里提问
但我怕问的不对,我再试一次,越简单越好
我有 2 个 table:
nn: id, name
nn_descr: id, long_description
nn_descr.id 和 nn.id 之间存在外键约束。
一般来说,与 nn_descr table.
相比,table 包含可以通过数据库引擎相当快速地搜索和管理的数据
现在我想以不同于所有 CRUD 创建者的方式管理这些数据。我想在我的 table 中创建 2 条相关记录,方法是在 JSF 表单上提交一次,该表单包含分别引用 nn.name 和 descr.long_description 的文本框和文本区域。
如果没有 JPA,我会在第一个 table 中插入记录,读取标识值并使用我已经读取的标识值将数据插入第二个 table。
对于 JPA,我应该以某种方式告诉该引擎神奇地保留数据。
这就是我不知道该怎么做的要点。无论我读到什么,都指的是简单的 CRUD,它可以通过我的 Netbeans 轻松生成。
我必须承认我迷失了这个 JPA、外观和所有生成的东西,但我试图通过做简单的应用程序来学习它
我设法让两个 table 中的记录都可更新。但是当我尝试插入数据时,我得到:
/nn/Create.xhtml @21,81 value="#{nnController.nnDescr.descr}": Target Unreachable, 'null' returned null
我一定是做错了什么,但我不知道在哪里可以找到答案、教程、书籍,任何比简单示例更深入的东西,其中有一个平面 table 和 CRUD table.
这是我的 JSF(尽可能基本):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="title">
<h:outputText value="#{boundle.CreateNnTitle}"></h:outputText>
</ui:define>
<ui:define name="body">
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="#{boundle.CreateNnLabel_nnName}" for="nnName" />
<h:inputText id="nnName" value="#{nnController.selected.nnName}" title="#{boundle.CreateNnTitle_nnName}" />
<h:outputLabel value="#{boundle.CreateNnLabel_nnDescr}" for="nnDescr" />
<h:inputTextarea id="nnDescr" value="#{nnController.selected.nnDescr.descr}" />
</h:panelGrid>
<br />
<h:commandLink action="#{nnController.create}" value="#{boundle.CreateNnSaveLink}" />
<br />
<br />
<h:commandLink action="#{nnController.prepareList}" value="#{boundle.CreateNnShowAllLink}" immediate="true"/>
<br />
<br />
<h:link outcome="/index" value="#{boundle.CreateNnIndexLink}"/>
</h:form>
</ui:define>
</ui:composition>
和控制器
package app;
import app.util.JsfUtil;
import app.util.PaginationHelper;
import java.io.Serializable;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
@Named("nnController")
@SessionScoped
public class NnController implements Serializable {
private Nn current;
private NnDescr nnDescr;
private DataModel items = null;
@EJB
private app.NnFacade ejbFacade;
private PaginationHelper pagination;
private int selectedItemIndex;
public NnController() {
}
public Nn getSelected() {
if (current == null) {
current = new Nn();
selectedItemIndex = -1;
}
return current;
}
private NnFacade getFacade() {
return ejbFacade;
}
public PaginationHelper getPagination() {
if (pagination == null) {
pagination = new PaginationHelper(10) {
@Override
public int getItemsCount() {
return getFacade().count();
}
@Override
public DataModel createPageDataModel() {
return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
}
};
}
return pagination;
}
public String prepareList() {
recreateModel();
return "List";
}
public String prepareView() {
current = (Nn) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "View";
}
public String prepareCreate() {
current = new Nn();
selectedItemIndex = -1;
return "Create";
}
public String create() {
try {
getFacade().create(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Boundle").getString("NnCreated"));
return prepareCreate();
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Boundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String prepareEdit() {
current = (Nn) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "Edit";
}
public String update() {
try {
getFacade().edit(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Boundle").getString("NnUpdated"));
return "View";
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Boundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String destroy() {
current = (Nn) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
performDestroy();
recreatePagination();
recreateModel();
return "List";
}
public String destroyAndView() {
performDestroy();
recreateModel();
updateCurrentItem();
if (selectedItemIndex >= 0) {
return "View";
} else {
// all items were removed - go back to list
recreateModel();
return "List";
}
}
private void performDestroy() {
try {
getFacade().remove(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Boundle").getString("NnDeleted"));
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Boundle").getString("PersistenceErrorOccured"));
}
}
private void updateCurrentItem() {
int count = getFacade().count();
if (selectedItemIndex >= count) {
// selected index cannot be bigger than number of items:
selectedItemIndex = count - 1;
// go to previous page if last page disappeared:
if (pagination.getPageFirstItem() >= count) {
pagination.previousPage();
}
}
if (selectedItemIndex >= 0) {
current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
}
}
public DataModel getItems() {
if (items == null) {
items = getPagination().createPageDataModel();
}
return items;
}
private void recreateModel() {
items = null;
}
private void recreatePagination() {
pagination = null;
}
public String next() {
getPagination().nextPage();
recreateModel();
return "List";
}
public String previous() {
getPagination().previousPage();
recreateModel();
return "List";
}
public SelectItem[] getItemsAvailableSelectMany() {
return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
}
public SelectItem[] getItemsAvailableSelectOne() {
return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
}
public Nn getNn(java.lang.Integer id) {
return ejbFacade.find(id);
}
public NnDescr getNnDescr() {
return nnDescr;
}
public void setNnDescr(NnDescr nnDescr) {
this.nnDescr = nnDescr;
}
@FacesConverter(forClass = Nn.class)
public static class NnControllerConverter implements Converter {
@Override
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
NnController controller = (NnController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "nnController");
return controller.getNn(getKey(value));
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuilder sb = new StringBuilder();
sb.append(value);
return sb.toString();
}
@Override
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Nn) {
Nn o = (Nn) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + Nn.class.getName());
}
}
}
}
Nn.java
package app;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.Size;
@Entity
@Table(name = "nn")
@NamedQueries({
@NamedQuery(name = "Nn.findAll", query = "SELECT n FROM Nn n"),
@NamedQuery(name = "Nn.findById", query = "SELECT n FROM Nn n WHERE n.id = :id"),
@NamedQuery(name = "Nn.findByNnName", query = "SELECT n FROM Nn n WHERE n.nnName = :nnName")})
public class Nn implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Size(max = 50)
@Column(name = "nn_name")
private String nnName;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "nn")
private NnDescr nnDescr;
public Nn() {
}
public Nn(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNnName() {
return nnName;
}
public void setNnName(String nnName) {
this.nnName = nnName;
}
public NnDescr getNnDescr() {
return nnDescr;
}
public void setNnDescr(NnDescr nnDescr) {
this.nnDescr = nnDescr;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Nn)) {
return false;
}
Nn other = (Nn) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "app.util.Nn[ id=" + id + " ]";
}
}
如您所见,数据已生成。我刚刚修改了生成的 JSF,以便有用于放置描述的文本区域。
我正在努力学习并花了很多时间试图弄清楚这一点,但没有任何效果。它不可能那么困难。我只是不明白一些明显的事情。
预先感谢您的帮助。
如果可能的话,如果有人可以 post 某个完整的例子来说明如何处理这样的问题,我将不胜感激。
value="#{nnController.nnDescr.descr}": Target Unreachable, 'null' returned null
这意味着 #{nnController}
或 #{nnController.nnDescr}
返回了 null
,因此 EL 无法调用 setter for descr
以便使用提交的输入值更新模型。
鉴于对 #{nnController}
的其他引用工作正常,#{nnController.nnDescr}
将返回 null
。实际上,您无处可在您的 bean 中准备它。
相应地修复它:
@PostConstruct
public void init() {
nnDescr = new NnDescr();
}
与具体问题无关,那个 bean 确实应该是视图范围的,而不是会话范围的。另见 How to choose the right bean scope?
也就是说,您最好从一本真正的书开始,以便根据真正的说明、解释和可行的方法学习 JSF snippets/examples,而不是在没有任何基础知识的情况下盲目地盯着自动生成的代码 knowledge/experience。您可以在 our JSF wiki page.
找到链接
谢谢,@PostConstruct 是我问题的正确答案。
另一个问题是如何正确地进行 JPA 映射,但这是另一个问题的主题。
我试着在这里提问 但我怕问的不对,我再试一次,越简单越好
我有 2 个 table:
nn: id, name
nn_descr: id, long_description
nn_descr.id 和 nn.id 之间存在外键约束。
一般来说,与 nn_descr table.
相比,table 包含可以通过数据库引擎相当快速地搜索和管理的数据现在我想以不同于所有 CRUD 创建者的方式管理这些数据。我想在我的 table 中创建 2 条相关记录,方法是在 JSF 表单上提交一次,该表单包含分别引用 nn.name 和 descr.long_description 的文本框和文本区域。
如果没有 JPA,我会在第一个 table 中插入记录,读取标识值并使用我已经读取的标识值将数据插入第二个 table。
对于 JPA,我应该以某种方式告诉该引擎神奇地保留数据。 这就是我不知道该怎么做的要点。无论我读到什么,都指的是简单的 CRUD,它可以通过我的 Netbeans 轻松生成。
我必须承认我迷失了这个 JPA、外观和所有生成的东西,但我试图通过做简单的应用程序来学习它
我设法让两个 table 中的记录都可更新。但是当我尝试插入数据时,我得到:
/nn/Create.xhtml @21,81 value="#{nnController.nnDescr.descr}": Target Unreachable, 'null' returned null
我一定是做错了什么,但我不知道在哪里可以找到答案、教程、书籍,任何比简单示例更深入的东西,其中有一个平面 table 和 CRUD table.
这是我的 JSF(尽可能基本):
<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://xmlns.jcp.org/jsf/facelets"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:f="http://xmlns.jcp.org/jsf/core">
<ui:composition template="/template.xhtml">
<ui:define name="title">
<h:outputText value="#{boundle.CreateNnTitle}"></h:outputText>
</ui:define>
<ui:define name="body">
<h:panelGroup id="messagePanel" layout="block">
<h:messages errorStyle="color: red" infoStyle="color: green" layout="table"/>
</h:panelGroup>
<h:form>
<h:panelGrid columns="2">
<h:outputLabel value="#{boundle.CreateNnLabel_nnName}" for="nnName" />
<h:inputText id="nnName" value="#{nnController.selected.nnName}" title="#{boundle.CreateNnTitle_nnName}" />
<h:outputLabel value="#{boundle.CreateNnLabel_nnDescr}" for="nnDescr" />
<h:inputTextarea id="nnDescr" value="#{nnController.selected.nnDescr.descr}" />
</h:panelGrid>
<br />
<h:commandLink action="#{nnController.create}" value="#{boundle.CreateNnSaveLink}" />
<br />
<br />
<h:commandLink action="#{nnController.prepareList}" value="#{boundle.CreateNnShowAllLink}" immediate="true"/>
<br />
<br />
<h:link outcome="/index" value="#{boundle.CreateNnIndexLink}"/>
</h:form>
</ui:define>
</ui:composition>
和控制器
package app;
import app.util.JsfUtil;
import app.util.PaginationHelper;
import java.io.Serializable;
import java.util.ResourceBundle;
import javax.ejb.EJB;
import javax.inject.Named;
import javax.enterprise.context.SessionScoped;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.convert.Converter;
import javax.faces.convert.FacesConverter;
import javax.faces.model.DataModel;
import javax.faces.model.ListDataModel;
import javax.faces.model.SelectItem;
@Named("nnController")
@SessionScoped
public class NnController implements Serializable {
private Nn current;
private NnDescr nnDescr;
private DataModel items = null;
@EJB
private app.NnFacade ejbFacade;
private PaginationHelper pagination;
private int selectedItemIndex;
public NnController() {
}
public Nn getSelected() {
if (current == null) {
current = new Nn();
selectedItemIndex = -1;
}
return current;
}
private NnFacade getFacade() {
return ejbFacade;
}
public PaginationHelper getPagination() {
if (pagination == null) {
pagination = new PaginationHelper(10) {
@Override
public int getItemsCount() {
return getFacade().count();
}
@Override
public DataModel createPageDataModel() {
return new ListDataModel(getFacade().findRange(new int[]{getPageFirstItem(), getPageFirstItem() + getPageSize()}));
}
};
}
return pagination;
}
public String prepareList() {
recreateModel();
return "List";
}
public String prepareView() {
current = (Nn) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "View";
}
public String prepareCreate() {
current = new Nn();
selectedItemIndex = -1;
return "Create";
}
public String create() {
try {
getFacade().create(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Boundle").getString("NnCreated"));
return prepareCreate();
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Boundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String prepareEdit() {
current = (Nn) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
return "Edit";
}
public String update() {
try {
getFacade().edit(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Boundle").getString("NnUpdated"));
return "View";
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Boundle").getString("PersistenceErrorOccured"));
return null;
}
}
public String destroy() {
current = (Nn) getItems().getRowData();
selectedItemIndex = pagination.getPageFirstItem() + getItems().getRowIndex();
performDestroy();
recreatePagination();
recreateModel();
return "List";
}
public String destroyAndView() {
performDestroy();
recreateModel();
updateCurrentItem();
if (selectedItemIndex >= 0) {
return "View";
} else {
// all items were removed - go back to list
recreateModel();
return "List";
}
}
private void performDestroy() {
try {
getFacade().remove(current);
JsfUtil.addSuccessMessage(ResourceBundle.getBundle("/Boundle").getString("NnDeleted"));
} catch (Exception e) {
JsfUtil.addErrorMessage(e, ResourceBundle.getBundle("/Boundle").getString("PersistenceErrorOccured"));
}
}
private void updateCurrentItem() {
int count = getFacade().count();
if (selectedItemIndex >= count) {
// selected index cannot be bigger than number of items:
selectedItemIndex = count - 1;
// go to previous page if last page disappeared:
if (pagination.getPageFirstItem() >= count) {
pagination.previousPage();
}
}
if (selectedItemIndex >= 0) {
current = getFacade().findRange(new int[]{selectedItemIndex, selectedItemIndex + 1}).get(0);
}
}
public DataModel getItems() {
if (items == null) {
items = getPagination().createPageDataModel();
}
return items;
}
private void recreateModel() {
items = null;
}
private void recreatePagination() {
pagination = null;
}
public String next() {
getPagination().nextPage();
recreateModel();
return "List";
}
public String previous() {
getPagination().previousPage();
recreateModel();
return "List";
}
public SelectItem[] getItemsAvailableSelectMany() {
return JsfUtil.getSelectItems(ejbFacade.findAll(), false);
}
public SelectItem[] getItemsAvailableSelectOne() {
return JsfUtil.getSelectItems(ejbFacade.findAll(), true);
}
public Nn getNn(java.lang.Integer id) {
return ejbFacade.find(id);
}
public NnDescr getNnDescr() {
return nnDescr;
}
public void setNnDescr(NnDescr nnDescr) {
this.nnDescr = nnDescr;
}
@FacesConverter(forClass = Nn.class)
public static class NnControllerConverter implements Converter {
@Override
public Object getAsObject(FacesContext facesContext, UIComponent component, String value) {
if (value == null || value.length() == 0) {
return null;
}
NnController controller = (NnController) facesContext.getApplication().getELResolver().
getValue(facesContext.getELContext(), null, "nnController");
return controller.getNn(getKey(value));
}
java.lang.Integer getKey(String value) {
java.lang.Integer key;
key = Integer.valueOf(value);
return key;
}
String getStringKey(java.lang.Integer value) {
StringBuilder sb = new StringBuilder();
sb.append(value);
return sb.toString();
}
@Override
public String getAsString(FacesContext facesContext, UIComponent component, Object object) {
if (object == null) {
return null;
}
if (object instanceof Nn) {
Nn o = (Nn) object;
return getStringKey(o.getId());
} else {
throw new IllegalArgumentException("object " + object + " is of type " + object.getClass().getName() + "; expected type: " + Nn.class.getName());
}
}
}
}
Nn.java
package app;
import java.io.Serializable;
import javax.persistence.Basic;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.validation.constraints.Size;
@Entity
@Table(name = "nn")
@NamedQueries({
@NamedQuery(name = "Nn.findAll", query = "SELECT n FROM Nn n"),
@NamedQuery(name = "Nn.findById", query = "SELECT n FROM Nn n WHERE n.id = :id"),
@NamedQuery(name = "Nn.findByNnName", query = "SELECT n FROM Nn n WHERE n.nnName = :nnName")})
public class Nn implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = false)
@Column(name = "id")
private Integer id;
@Size(max = 50)
@Column(name = "nn_name")
private String nnName;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "nn")
private NnDescr nnDescr;
public Nn() {
}
public Nn(Integer id) {
this.id = id;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getNnName() {
return nnName;
}
public void setNnName(String nnName) {
this.nnName = nnName;
}
public NnDescr getNnDescr() {
return nnDescr;
}
public void setNnDescr(NnDescr nnDescr) {
this.nnDescr = nnDescr;
}
@Override
public int hashCode() {
int hash = 0;
hash += (id != null ? id.hashCode() : 0);
return hash;
}
@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Nn)) {
return false;
}
Nn other = (Nn) object;
if ((this.id == null && other.id != null) || (this.id != null && !this.id.equals(other.id))) {
return false;
}
return true;
}
@Override
public String toString() {
return "app.util.Nn[ id=" + id + " ]";
}
}
如您所见,数据已生成。我刚刚修改了生成的 JSF,以便有用于放置描述的文本区域。
我正在努力学习并花了很多时间试图弄清楚这一点,但没有任何效果。它不可能那么困难。我只是不明白一些明显的事情。
预先感谢您的帮助。
如果可能的话,如果有人可以 post 某个完整的例子来说明如何处理这样的问题,我将不胜感激。
value="#{nnController.nnDescr.descr}": Target Unreachable, 'null' returned null
这意味着 #{nnController}
或 #{nnController.nnDescr}
返回了 null
,因此 EL 无法调用 setter for descr
以便使用提交的输入值更新模型。
鉴于对 #{nnController}
的其他引用工作正常,#{nnController.nnDescr}
将返回 null
。实际上,您无处可在您的 bean 中准备它。
相应地修复它:
@PostConstruct
public void init() {
nnDescr = new NnDescr();
}
与具体问题无关,那个 bean 确实应该是视图范围的,而不是会话范围的。另见 How to choose the right bean scope?
也就是说,您最好从一本真正的书开始,以便根据真正的说明、解释和可行的方法学习 JSF snippets/examples,而不是在没有任何基础知识的情况下盲目地盯着自动生成的代码 knowledge/experience。您可以在 our JSF wiki page.
找到链接谢谢,@PostConstruct 是我问题的正确答案。 另一个问题是如何正确地进行 JPA 映射,但这是另一个问题的主题。