Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/13.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 将模型中的筛选列表带入视图_Java_Spring_Hibernate_Jsp_Jpa 2.0 - Fatal编程技术网

Java 将模型中的筛选列表带入视图

Java 将模型中的筛选列表带入视图,java,spring,hibernate,jsp,jpa-2.0,Java,Spring,Hibernate,Jsp,Jpa 2.0,我的spring mvc hibernate应用程序有三个Pet对象列表(pets,cats,dogs),它们填充在模型中(一个Owner类),需要由控制器(OwnerController.java)发送到视图(一个映射到/owners url模式的jsp)。所有三个列表都应从基础数据库中相同的pets表中填充,pets列表包括pets表中的所有列表,cats列表仅包括pets表中属于cats的条目,而狗列表仅包括宠物表中的狗条目问题是,所有三个列表中都填充了所有宠物,而不管它们是什么类型。我已

我的spring mvc hibernate应用程序有三个
Pet
对象列表(
pets
cats
dogs
),它们填充在模型中(一个
Owner
类),需要由控制器(OwnerController.java)发送到视图(一个映射到/owners url模式的jsp)。所有三个列表都应从基础数据库中相同的
pets
表中填充,
pets
列表包括
pets
表中的所有列表,
cats
列表仅包括
pets
表中属于cats的条目,而
列表仅包括
宠物
表中的狗条目问题是,所有三个列表中都填充了所有宠物,而不管它们是什么类型。我已经通过System.out.println()命令确认,列表填充问题发生在模型的级别上。如何使
列表仅包含猫,而
列表仅包含狗

下面是来自模型Owner.java的相关代码:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner")
private Set<Pet> pets;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER)
private Set<Pet> cats;

@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER)
private Set<Pet> dogs;

protected void setPetsInternal(Set<Pet> pets) {this.pets = pets;}

// Call this from OwnerController before returning data to page.
public void parsePets() {
    for (Pet pet : getPetsInternal()) {
        if (pet.getType().getName().equals("cat")) {
            cats.add(pet);
            System.out.println(pet.getType().getName());
            System.out.println("cats.size() is: "+cats.size());
            System.out.println("added a cat to cats");
        } 
        else if (pet.getType().getName().equals("dog")) {
            dogs.add(pet);
            System.out.println(pet.getType().getName());
            System.out.println("dogs.size() is: "+dogs.size());
            System.out.println("added a dog to dogs");
        }
        // add as many as you want
        System.out.println("-----------------------------------------------------------");
      }
    }

public Set<Pet> getCats() {
    System.out.println("about to return cats");
    for (Pet cat : cats) {System.out.println("counting a "+cat.getType()+" in cats.");}
    System.out.println("cats.size() is: "+cats.size());
    return cats;
}

public Set<Pet> getDogs() {
    System.out.println("about to return dogs");
    for (Pet dog : cats) {System.out.println("counting a "+dog.getType()+" in dogs.");}
    System.out.println("dogs.size() is: "+dogs.size());
    return dogs;
}

protected Set<Pet> getPetsInternal() {
    if (this.pets == null) {this.pets = new HashSet<Pet>();}
    return this.pets;
}

public List<Pet> getPets() {
    List<Pet> sortedPets = new ArrayList<Pet>(getPetsInternal());
    PropertyComparator.sort(sortedPets, new MutableSortDefinition("name", true, true));
    return Collections.unmodifiableList(sortedPets);
}  
@RequestMapping(value = "/owners", method = RequestMethod.GET)
public String processFindForm(@RequestParam("ownerID") String ownerId, Owner owner, BindingResult result, Map<String, Object> model) {
    Collection<Owner> results = this.clinicService.findOwnerByLastName("");
    model.put("selections", results);
    int ownrId = Integer.parseInt(ownerId);
    Owner sel_owner = this.clinicService.findOwnerById(ownrId);
    sel_owner.parsePets();
    model.put("sel_owner",sel_owner);
    return "owners/ownersList";
}
请注意,Cat和Dog没有定义为类,因为在这一点上,它们存储的信息或方法与pets不同,我想简化代码。我需要上猫课和狗课吗?或者我可以在不创建单独类的情况下解决此问题吗


第二次编辑: 我在猫和狗的声明之前添加了@Transactional并注释掉了//@OneToMany(…),但在宠物声明之前保留了@OneToMany(…)注释。我还补充说

= new HashSet<Pet>();  
business-config.xml的代码谁能告诉我如何解决这个问题

我可以通过注释更改来消除错误消息并让应用程序运行,但接下来的问题是三个列表(宠物、猫、狗)是相同的,而我需要猫和狗都是宠物的不同子集。以下代码消除了错误消息,但创建了三个不应相同的相同列表:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner",  fetch=FetchType.EAGER)
private Set<Pet> pets;

//I added next two variables
//    @Transient
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER)
private Set<Pet> cats;// = new HashSet<Pet>();

//    @Transient  
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER)  
private Set<Pet> dogs;// = new HashSet<Pet>();  
@OneToMany(cascade=CascadeType.ALL,mappedBy=“owner”,fetch=FetchType.EAGER)
私人宠物;
//我添加了接下来的两个变量
//@Transient
@OneToMany(cascade=CascadeType.ALL,mappedBy=“owner”,fetch=FetchType.EAGER)
私人套装猫;//=新HashSet();
//@Transient
@OneToMany(cascade=CascadeType.ALL,mappedBy=“owner”,fetch=FetchType.EAGER)
私家狗;//=新HashSet();

您需要删除猫和狗的休眠映射!仅通过hibernate将(内部)
pets
列表映射到数据库。然后过滤掉猫和狗(就像你已经做的那样)

如果要添加宠物,请确保它们已添加到(内部)
pets
列表中

@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner",  fetch=FetchType.EAGER)
private Set<Pet> pets;

/**
 * Selection of cats from pets, it is a COPY!
 * Lazy populated cache, set it to NULL for invalidation.
 * The set itself is unmodifiable!
 */
@Transient
private Set<Pet> catsCache;

/** the same for dogs: @Transient private Set<Pet> dogsCache; */

public Set<Pet> getPets() {
    return Collections.<Pet>unmodifiableCollection(this.pet);
}

public Set<Pet> getCats() {
    if (this.catsCache == null) {
        Set<Pet> catsSelection = new HashSet();
        for (Pet pet : this.pets) {
           //assume pet.type is an emum called PetType wiht an enumaration cat, if this does
           //not exist, then use: if (pet.getType().getName().equals("cat"))
           if (pet.getType() == PetType.cat)
               catsSelection.add(pet);
        }
        this.catsCache = Collections.<Pet>unmodifiableCollection(catsSelection);
    }
    return this.catsCache;
}

public void addPet(Pet catOrDog) {
    this.pets.add(catOrDog);
    this.catsCache = null;
}
@OneToMany(cascade=CascadeType.ALL,mappedBy=“owner”,fetch=FetchType.EAGER)
私人宠物;
/**
*从宠物猫的选择,这是一个副本!
*惰性填充缓存,将其设置为NULL以使其无效。
*集合本身是不可修改的!
*/
@短暂的
私用套猫;
/**狗也是一样:@Transient private Set dogsCache*/
公共集getPets(){
返回集合。不可修改集合(this.pet);
}
公共集getCats(){
if(this.catsCache==null){
Set catsSelection=new HashSet();
用于(宠物:this.pets){
//假设pet.type是一个名为PetType的emum,带有枚举cat,如果这样做的话
//不存在,则使用:if(pet.getType().getName().equals(“cat”))
if(pet.getType()==PetType.cat)
CATS选择。添加(pet);
}
this.catsCache=Collections.unmodifiableCollection(catsSelection);
}
退回这个.catsCache;
}
公共空间添加宠物(宠物猫){
这个.pets.add(catOrDog);
this.catsCache=null;
}

如果你想坚持你的方法,就要做
瞬变,这样JPA就不会试图映射字段或用实体填充字段:

@Transient
private Set<Pet> cats = new HashSet<Pet>();

@Transient
private Set<Pet> dogs = new HashSet<Pet>();
@Transient
私有集cats=newhashset();
@短暂的
私有集dogs=newhashset();

如果您想实现
Dog
Cat
类来建立继承关系,您可以遵循我所做的这一点。

Do
Cat
Dog
扩展一些基类吗?我猜,
Pet
?@KevinBowersox猫和狗不作为类存在。只有宠物是一个类。
Owner
Pet
之间的关系是双向的吗?@KevinBowersox一个主人可以养很多宠物,但是每个宠物只能有一个主人。@CodeMed这些字段必须用
@Transient
注释,否则JPA将尝试映射该字段。@Ralph我在上面显示当前错误的原始帖子中添加了第二次编辑。你愿意花点时间帮我解决这个问题吗?我已经被这个问题的各种变化困扰了几天,并且尝试了许多不同的方法,但都没有成功。如果你能写一个明确的代码解决方案,你将真正教育我。@CodeMed:我添加了一个example@Ralph非常感谢你的帮助。我开始使用您的代码,但是eclipse给了我错误,因为我的应用程序中没有Cat类。然后,当我克隆了Pet类并将其重命名为Cat时,代码中的错误包括Pet无法转换为Cat,以及PetType没有子类型Cat。我可以编写很多复杂的代码来测试您添加的内容。我们可以创建一个名为“猫”的列表,该列表由猫的宠物子集填充吗?基于hibernate where子句?是我的错,我想你有一个子类Cat。-我修改了示例中的代码。我在上面的原始帖子中添加了第二个编辑,它更完整地描述了当前错误。有什么想法吗?
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner",  fetch=FetchType.EAGER)
private Set<Pet> pets;

//I added next two variables
//    @Transient
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER)
private Set<Pet> cats;// = new HashSet<Pet>();

//    @Transient  
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER)  
private Set<Pet> dogs;// = new HashSet<Pet>();  
@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner",  fetch=FetchType.EAGER)
private Set<Pet> pets;

/**
 * Selection of cats from pets, it is a COPY!
 * Lazy populated cache, set it to NULL for invalidation.
 * The set itself is unmodifiable!
 */
@Transient
private Set<Pet> catsCache;

/** the same for dogs: @Transient private Set<Pet> dogsCache; */

public Set<Pet> getPets() {
    return Collections.<Pet>unmodifiableCollection(this.pet);
}

public Set<Pet> getCats() {
    if (this.catsCache == null) {
        Set<Pet> catsSelection = new HashSet();
        for (Pet pet : this.pets) {
           //assume pet.type is an emum called PetType wiht an enumaration cat, if this does
           //not exist, then use: if (pet.getType().getName().equals("cat"))
           if (pet.getType() == PetType.cat)
               catsSelection.add(pet);
        }
        this.catsCache = Collections.<Pet>unmodifiableCollection(catsSelection);
    }
    return this.catsCache;
}

public void addPet(Pet catOrDog) {
    this.pets.add(catOrDog);
    this.catsCache = null;
}
@Transient
private Set<Pet> cats = new HashSet<Pet>();

@Transient
private Set<Pet> dogs = new HashSet<Pet>();