【问题标题】:Primefaces 5 JSF 2.2 h:selectOneMenu populates child menu with wrong dataPrimefaces 5 JSF 2.2 h:selectOneMenu 使用错误数据填充子菜单
【发布时间】:2014-10-14 01:00:00
【问题描述】:

我有一个 maven-hibernate-primefaces 项目,其中包含三个嵌套的 h:selectOneMenu (Country -> City -> Address),如下所示,

<h:outputLabel for="countryList" value="Countries" />
<h:selectOneMenu id="countryList" value="#{userBean.newCountry}" converter="omnifaces.SelectItemsConverter" >
  <f:selectItem itemValue="#{userBean.selectedCountry}"
             itemLabel="#{userBean.selectedCountry.country}" />
  <f:selectItems value="#{userBean.countries}" var="country" 
             itemValue="#{country}" itemLabel="#{country.country}"/>
  <f:ajax listener="#{userBean.loadCities}" render="cityList" />
</h:selectOneMenu>

<h:outputLabel for="cityList" value="Cities" />
<h:selectOneMenu id="cityList" value="#{userBean.newCity}" converter="omnifaces.SelectItemsConverter" >
  <f:selectItem itemValue="#{null}" itemLabel="Select city" />
  <f:selectItems value="#{userBean.cities}" var="city"
             itemValue="#{city}" itemLabel="#{city.city}" />
  <f:ajax listener="#{userBean.loadAddresses}" render="addressList" />
</h:selectOneMenu>

<h:outputLabel for="addressList" value="Address" />
<h:selectOneMenu id="addressList" value="#{userBean.newAddress}"  converter="omnifaces.SelectItemsConverter" >
  <f:selectItem itemValue="#{null}" itemLabel="Select address" />
  <f:selectItems value="#{userBean.addresses}" var="address"
             itemValue="#{address}" itemLabel="#{address.address} #{address.address2}" />
</h:selectOneMenu>

从userBean我有如下相应的属性和方法,

private Users newUser = new Users();
private Employees newEmployee = new Employees();
private Department newDepartment = new Department();
private Address newAddress = new Address();
private City newCity = new City();
private Country newCountry = new Country();
private Users selectedUser;
private Employees selectedEmployee;
private Department selectedDepartment;
private Address selectedAddress;
private City selectedCity;
private Country selectedCountry;
private List<Users> users = new ArrayList<>();
private List<Employees> employees = new ArrayList<>();
private List<Department> departments = new ArrayList<>();
private List<Address> addresses = new ArrayList<>();
private List<City> cities = new ArrayList<>();
private List<Country> countries = new ArrayList<>();

public void loadCities() {
    cities = CountryDAO.findCitiesOfCountry(sessionFactory, newCountry);
}

public void loadAddresses() {
    addresses = CityDAO.findAddressesOfCity(sessionFactory, newCity);
}

public void changeEmployee(SelectEvent event) {
    selectedEmployee = (Employees) event.getObject();
    selectedDepartment = EmployeeDAO.findDepartmentOfEmployee(sessionFactory, selectedEmployee);
    selectedAddress = EmployeeDAO.findAddressOfEmployee(sessionFactory, selectedEmployee);
    selectedCity = AddressDAO.findCityOfAddress(sessionFactory, selectedAddress);
    selectedCountry = CityDAO.findCountryOfCity(sessionFactory, selectedCity);
}

方法“changeEmployee”从员工数据表的一行中选择一个员工,所以我创建了不同的调用,直到获得一个选定的国家/地区到他所属的国家

这一切都很好。问题在于 selectOneMenu,

国家DAO

public static List<City> findCitiesOfCountry(SessionFactory sessionFactory, Country country) {

    List<City> myCityList;

    Session session = sessionFactory.openSession();

    //start transaction
    session.beginTransaction();

    String hql = "from Country c join fetch c.cityList where c.countryId = :countryId";
    Country ctry = (Country) session.createQuery(hql)
                        .setShort("countryId", country.getCountryId())
                        .list().get(0);
    myCityList = ctry.getCityList();

    //Commit transaction
    session.getTransaction().commit();

    session.close();


    return myCityList;
}

CityDAO

public static List<Address> findAddressesOfCity(SessionFactory sessionFactory, City city) {

    List<Address> myAddressList;

    Session session = sessionFactory.openSession();

    //start transaction
    session.beginTransaction();

    String hql = "from City c join fetch c.addressList where c.cityId = :cityId";
    City cty = (City) session.createQuery(hql)
                        .setShort("cityId", city.getCityId())
                        .list().get(0);
    myAddressList = cty.getAddressList();

    //Commit transaction
    session.getTransaction().commit();

    session.close();

    return myAddressList;
}

虽然列表是填充的,但它们带有错误的数据。

这里有 hbm 映射文件,

国家.hbm.xml

<hibernate-mapping>
<class name="com.journaldev.hibernate.model.Country" table="country">
    <id name="countryId" type="java.lang.Short" column="COUNTRY_ID" >
        <generator class="native" />
    </id> 
    <property name="country" type="java.lang.String">
      <column name="COUNTRY"/>
    </property>
    <property name="lastUpdate" type="timestamp">
      <column name="LAST_UPDATE"/>
    </property>
    <bag name="cityList" table="city"
            inverse="true" lazy="true" fetch="select">
        <key>
            <column name="city_id" not-null="true" />
        </key>
        <one-to-many class="com.journaldev.hibernate.model.City" />
    </bag>
</class>
</hibernate-mapping>

city.hbm.xml

<hibernate-mapping>
<class name="com.journaldev.hibernate.model.City" table="city">
    <id name="cityId" type="java.lang.Short" column="CITY_ID" >
        <generator class="native" />
    </id>
    <property name="city" type="java.lang.String">
      <column name="CITY"/>
    </property>
    <property name="lastUpdate" type="timestamp">
      <column name="LAST_UPDATE"/>
    </property>
    <bag name="addressList" table="address"
            inverse="true" lazy="true" fetch="select">
        <key>
            <column name="ADDRESS_ID" not-null="true" />
        </key>
        <one-to-many class="com.journaldev.hibernate.model.Address" />
    </bag>
    <many-to-one name="country" class="com.journaldev.hibernate.model.Country" fetch="select">
        <column name="COUNTRY_ID" not-null="true" />
    </many-to-one>
</class>
</hibernate-mapping>

地址.hbm.xml

<hibernate-mapping>
<class name="com.journaldev.hibernate.model.Address" table="address">
    <id name="addressId" type="java.lang.Short" column="ADDRESS_ID" >
        <generator class="native" />
    </id>
    <property name="address" type="java.lang.String">
      <column name="ADDRESS"/>
    </property>
    <property name="address2" type="java.lang.String">
      <column name="ADDRESS2"/>
    </property>
    <property name="district" type="java.lang.String">
      <column name="DISTRICT"/>
    </property>
    <property name="postalCode" type="java.lang.String">
      <column name="POSTAL_CODE"/>
    </property>
    <property name="phone" type="java.lang.String">
      <column name="PHONE"/>
    </property>
    <property name="lastUpdate" type="timestamp">
      <column name="LAST_UPDATE"/>
    </property>
    <many-to-one name="city" class="com.journaldev.hibernate.model.City" fetch="select">
        <column name="city_id" not-null="true" />
    </many-to-one>
    <bag name="employeesList" table="EMPLOYEES"
            inverse="true" lazy="true" fetch="select">
        <key>
            <column name="id" not-null="true" />
        </key>
        <one-to-many class="com.journaldev.hibernate.model.Employees" />
    </bag>
</class>
</hibernate-mapping>

当我执行 Primefaces 页面国家列表时没问题,但跟随嵌套的孩子我得到了错误的数据。

女巫有问题吗?我的代码哪里出错了?

谢谢

【问题讨论】:

  • 我没有看到任何 primefaces 组件?您是否进行了调试以了解问题出在 facelet 还是模型中?什么是错误的数据,来自另一个城市的地址?
  • 嗨。当我说错误数据时,我的意思是子菜单中的值与所选父菜单不对应(在所有情况下)。
  • 让我展示一下 glassfish 在我部署 web 应用程序时显示的内容,WARNING: Parameter 1 of type java.util.Map&lt;java.lang.String, java.util.List&lt;javax.enterprise.inject.spi.Bean&lt;?&gt;&gt;&gt; from public void org.omnifaces.cdi.eager.EagerBeansRepository.setRequestScopedBeansViewId(java.util.Map&lt;java.lang.String, java.util.List&lt;javax.enterprise.inject.spi.Bean&lt;?&gt;&gt;&gt;) is not resolvable to a concrete type. 我想我的列表还不够完善
  • 这是我的错误。我再次完成了代码,现在工作正常。谢谢。

标签: hibernate jsf-2 primefaces


【解决方案1】:

这里是hibernate ORM就是选择每个h:selectOneMenu的内容的方法,

@PostConstruct
public void initUsers() {
    HttpSession session = HttpSessionUtil.getSession(false);
    sessionFactory = (SessionFactory) session.getAttribute("sessionFactory");

    -------------------
    -------------------
    countries = CountryDAO.listCountries(sessionFactory);
}

public void loadCities() {
    cities = CityDAO.findCitiesOfCountry(sessionFactory, newCountry);
}

public void loadAddresses() {
    addresses = AddressDAO.findAddressesOfCity(sessionFactory, newCity);
}

我在 post 构造方法中获得完整的国家列表,然后根据每个选定的项目,我将把内容提供给其他人 selectOneMenu Primefaces页面如下,

<h:outputLabel for="countryList" value="Countries" />
<h:selectOneMenu id="countryList" value="#{userBean.newCountry}" converter="omnifaces.SelectItemsConverter" >
    <f:selectItem itemValue="#{userBean.selectedCountry}" itemLabel="#{userBean.selectedCountry.country}" />
    <f:selectItems value="#{userBean.countries}" var="country" 
                                   itemValue="#{country}" itemLabel="#{country.country}"/>
    <f:ajax listener="#{userBean.loadCities}" render="cityList" />
</h:selectOneMenu>

<h:outputLabel for="cityList" value="Cities" />
<h:selectOneMenu id="cityList" value="#{userBean.newCity}" converter="omnifaces.SelectItemsConverter" >
    <f:selectItem itemValue="#{userBean.selectedCity}" itemLabel="#{userBean.selectedCity.city}" />
    <f:selectItems value="#{userBean.cities}" var="city"
                                   itemValue="#{city}" itemLabel="#{city.city}" />
    <f:ajax listener="#{userBean.loadAddresses}" render="addressList" />
</h:selectOneMenu>

<h:outputLabel for="addressList" value="Address" />
<h:selectOneMenu id="addressList" value="#{userBean.newAddress}" converter="omnifaces.SelectItemsConverter" >
    <f:selectItem itemValue="#{userBean.selectedAddress}" itemLabel="#{userBean.selectedAddress.address}" />
    <f:selectItems value="#{userBean.addresses}" var="address"
                                   itemValue="#{address}" itemLabel="#{address.address}" />
</h:selectOneMenu>

这种方式现在可以正常工作了。您可以在 http://www.josealvarezdelara.com/HibernateWebApp-0.0.1-SNAPSHOT/ui/home.jsf 看到工作,其中 Jose Alvarez de Lara 是我

【讨论】:

猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2013-11-01
  • 1970-01-01
  • 2013-04-13
  • 2014-08-29
  • 1970-01-01
  • 2011-08-17
  • 2014-01-25
相关资源
最近更新 更多