添加两个变量后的BeanCreationException [英] BeanCreationException after adding two variables

查看:74
本文介绍了添加两个变量后的BeanCreationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有人能告诉我如何通过BeanCreationException吗?



在将两个变量添加到 Owner.java 如下:

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

//我添加了以下两个变量声明
@Transient
private Set< Pet> cats = new HashSet< Pet>();

@Transient
私人设定< Pet> dogs = new HashSet< Pet>();

我还为猫和狗添加了getter和setter方法,以及用于填充猫和狗的方法(Pet pet:getPetsInternal())作为宠物的子集,如下所示:

  public void parsePets(){
{
if(pet.getType()。getName()。equals(cat)){cats.add(pet);}
else if(pet.getType()。getName()。等于(狗)){dogs.add(pet);}
}
}

保护设置< Pet> getPetsInternal(){
if(this.pets == null){this.pets = new HashSet< Pet>();}
return this.pets;
}

当我运行为...时,应用程序无法初始化运行在eclipse中的服务器,并提供以下错误信息:

  org.springframework.beans.factory.BeanCreationException:
创建名为
的bean时出错错误org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0'
在类路径资源[spring / business-config.xml]中定义:初始化bean失败;
嵌套的异常是org.springframework.beans.factory.BeanCreationException:
在类路径资源
[spring / business-config.xml]中定义的名称为'entityManagerFactory'的Bean创建错误:调用init方法失败;
嵌套异常是javax.persistence.PersistenceException:
[PersistenceUnit:petclinic]无法构建EntityManagerFactory

...

引起:org。 hibernate.MappingException:
无法确定类型:
java.util.Set,表中:所有者,列:
[org.hibernate.mapping.Column(cats)]

以下是 business-config.xml的代码



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

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

//我添加了两个变量
// @Transient
@OneToMany(cascade = CascadeType.ALL,mappedBy =owner,fetch = FetchType.EAGER)
私人套餐<宠物> cats; // = new HashSet< Pet>();

// @Transient
@OneToMany(cascade = CascadeType.ALL,mappedBy =owner,fetch = FetchType.EAGER)
private Set< Pet>狗; // =新的HashSet< Pet>();根据axiopisty的要求,除了猫和狗之外,我不能真正评论一切,因为宠物,猫并且狗从OwnerController.java调用如下:

  @RequestMapping(value =/ owners,method = RequestMethod.GET )
public String processFindForm(@RequestParam(ownerID)字符串ownerId,所有者所有者,BindingResult结果,Map< String,Object>模型){
Collection< Owner> results = this.clinicService.findOwnerByLastName();
model.put(选择,结果);
int ownrId = Integer.parseInt(ownerId);
所有者sel_owner = this.clinicService.findOwnerById(ownrId); // jim添加了这个$​​ b $ b sel_owner.parsePets();
model.put(sel_owner,sel_owner);
返回owners / ownersList;






编辑:



根据Sotirios的要求,这里是我的实体类Owner.java:

  @Entity 
@Table(name =owners)
公共类拥有者扩展Person {
@Column(name =address)
@NotEmpty
私人字符串地址;

@Column(name =city)
@NotEmpty
private String city;

@Column(name =telephone)
@NotEmpty
@Digits(fraction = 0,integer = 10)
private String telephone;

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

//我添加了下面两个变量
@Transient
@OneToMany(cascade = CascadeType.ALL,mappedBy =owner,fetch = FetchType.EAGER)
私人套餐<宠物> cats = new HashSet< Pet>();

@Transient
@OneToMany(cascade = CascadeType.ALL,mappedBy =owner,fetch = FetchType.EAGER)
private Set< Pet> dogs = new HashSet< Pet>();
// 2个变量的末尾我添加了

public String getAddress(){return this.address;}
$ b $ public void setAddress(String address){this。地址=地址;}

public String getCity(){return this.city;}

public void setCity(String city){this.city = city;}

public String getTelephone(){return this.telephone;}

public void setTelephone(String telephone){this.telephone = telephone;}

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

//在将数据返回给页​​面之前,从OwnerController调用此函数。 $()petb:getPetsInternal()){
if(pet.getType()。getName()。equals(cat)){$ b $ public b $ b public void parsePets(){
$ b cats.add(pet);
System.out.println(pet.getType()。getName());
System.out.println(cats.size()is:+ cats.size());
System.out.println(向猫添加猫);
}
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(添加狗给狗);
}
//添加尽可能多的
System.out.println(---------------------- ------------------------);
}
}

public Set< Pet> getCats(){
System.out.println(关于返回猫); (cat猫){System.out.println(在猫中计数+ cat.getType()+);}
System.out.println(cats。 size()是:+ cats.size());
归还猫;
}

public Set< Pet> getDogs(){
System.out.println(关于返回狗);
for(Pet dog:dogs){System.out.println(在狗中计数+ dog.getType()+);}
System.out.println(dogs。 size()是:+ dogs.size());
归来狗;
}

//结尾部分我添加了

保护套< Pet> getPetsInternal(){
if(this.pets == null){this.pets = new HashSet< Pet>();}
return this.pets;
}


公开列表< Pet> getPets(){
List< Pet> sortedPets = new ArrayList< Pet>(getPetsInternal());
PropertyComparator.sort(sortedPets,new MutableSortDefinition(name,true,true));
返回Collections.unmodifiableList(sortedPets);
}

public void addPet(Pet pet){
getPetsInternal()。add(pet);
pet.setOwner(this);
}
$ b $ public Pet getPet(String name){return getPet(name,false);}
$ b $ public getPet(String name,boolean ignoreNew){
name = name.toLowerCase(); ($ pet $:
for(Pet pet:getPetsInternal()){
if(!ignoreNew ||!pet.isNew()){
String compName = pet.getName();
compName = compName.toLowerCase();
if(compName.equals(name)){
return pet;
}
}
}
返回null;
}

@Override
public String toString(){
返回新的ToStringCreator(this)

.append(id, this.getId())
.append(new,this.isNew())
.append(lastName,this.getLastName())
.append(firstName ,this.getFirstName())
.append(address,this.address)
.append(city,this.city)
.append(telephone,this。电话)
.toString();
}
}


解决方案

单独列表必须是实例变量?!为什么不简单地创建 getCats 方法(以及其他方法),并简单地过滤 pets 集合?试图映射一切,使得事情过于复杂。

  @Entity 
@Table(name =owners)
public class Owner extends Person {

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

public Set< Pet> getCats(){
Set< Pet> cats = new HashSet< Pet>(); (pet pet:getPetsInternal()){
if(pet.getType()。getName()。equals(cat)){
cats.add(pet);

}
}
返回猫;




$ b $ p
$ b

缺点是每次需要时都会重新创建集合。

  @Entity 
@Table(name = 所有者)
公共类所有者扩展人{

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

public Set< Pet> getCats(){
返回Sets.filter(getPetsInternal(),new Predicate< Pet>(){
public boolean apply(Pet pet){
return pet.getType()。getName ).equals(cat)
}
});


$ / code>

你也可以在 parsePets 方法,并用 @PostLoad 对其进行注释,以便在拥有者从数据库中检索后调用该方法。

Can someone show me how to get past a BeanCreationException?

I am getting a BeanCreationException after adding two variables to Owner.java as follows:

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

//I added the following two variable declarations
@Transient
private Set<Pet> cats = new HashSet<Pet>();

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

I also added getter and setter methods for cats and dogs, along with a method for populating cats and dogs as subsets of pets as follows:

public void parsePets() {
    for (Pet pet : getPetsInternal()) {
    if (pet.getType().getName().equals("cat")) {cats.add(pet);} 
    else if (pet.getType().getName().equals("dog")) {dogs.add(pet);}
  }
}

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

The application is failing to initialize when I do Run As...Run on Server within eclipse, and is giving the following error message:

org.springframework.beans.factory.BeanCreationException:  
Error creating bean with name  
'org.springframework.dao.annotation.PersistenceExceptionTranslationPostProcessor#0'  
defined in class path resource [spring/business-config.xml]: Initialization of bean failed;  
nested exception is org.springframework.beans.factory.BeanCreationException:  
Error creating bean with name 'entityManagerFactory' defined in class path resource  
[spring/business-config.xml]: Invocation of init method failed;  
nested exception is javax.persistence.PersistenceException:  
[PersistenceUnit: petclinic] Unable to build EntityManagerFactory  

...  

Caused by: org.hibernate.MappingException:  
Could not determine type for:  
java.util.Set, at table: owners, for columns:  
[org.hibernate.mapping.Column(cats)]

Here is the code for business-config.xml.

I can eliminate the error message and get the application to run by commenting out the changes, but then I am left with the problem that the three lists (pets, cats, dogs) are identical, when I need cats and dogs to each be different subsets of pets. Here is the code which eliminates the error message but creates three identical lists which should not be identical:

@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>();   

Per axiopisty's request, I cannot really comment out everything except the addition of cats and dogs because pets, cats and dogs are called from OwnerController.java as follows:

@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);//jim added this
    sel_owner.parsePets();
    model.put("sel_owner",sel_owner);
    return "owners/ownersList";
}  


EDIT:

As per Sotirios' request, here is my entity class, Owner.java:

@Entity
@Table(name = "owners")
public class Owner extends Person {
    @Column(name = "address")
    @NotEmpty
    private String address;

    @Column(name = "city")
    @NotEmpty
    private String city;

    @Column(name = "telephone")
    @NotEmpty
    @Digits(fraction = 0, integer = 10)
    private String telephone;

    @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>();
    //end of 2 variables I added

    public String getAddress() {return this.address;}

    public void setAddress(String address) {this.address = address;}

    public String getCity() {return this.city;}

    public void setCity(String city) {this.city = city;}

    public String getTelephone() {return this.telephone;}

    public void setTelephone(String telephone) {this.telephone = telephone;}

    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 : dogs) {System.out.println("counting a "+dog.getType()+" in dogs.");}
        System.out.println("dogs.size() is: "+dogs.size());
        return dogs;
    }

    //end section I added

    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);
    }

    public void addPet(Pet pet) {
        getPetsInternal().add(pet);
        pet.setOwner(this);
    }

    public Pet getPet(String name) {return getPet(name, false);}

    public Pet getPet(String name, boolean ignoreNew) {
        name = name.toLowerCase();
        for (Pet pet : getPetsInternal()) {
            if (!ignoreNew || !pet.isNew()) {
                String compName = pet.getName();
                compName = compName.toLowerCase();
                if (compName.equals(name)) {
                    return pet;
                }
            }
        }
        return null;
    }

    @Override
    public String toString() {
        return new ToStringCreator(this)

            .append("id", this.getId())
            .append("new", this.isNew())
            .append("lastName", this.getLastName())
            .append("firstName", this.getFirstName())
            .append("address", this.address)
            .append("city", this.city)
            .append("telephone", this.telephone)
            .toString();
    }
}

解决方案

Why do the seperate lists have to be instance variables?! Why not simply create a getCats method (and the others) and simply filter the pets collection? Trying to map everything makes, imho, things overly complex.

@Entity
@Table(name = "owners")
public class Owner extends Person {

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

    public Set<Pet> getCats() {
        Set<Pet> cats = new HashSet<Pet>();
        for (Pet pet : getPetsInternal()) {
            if (pet.getType().getName().equals("cat")) {
                cats.add(pet);
            }
        }
        return cats;
    }
}

Drawback is that the collection is recreated every time when needed. You can ease this with something like Google Guava and create a filter list.

@Entity
@Table(name = "owners")
public class Owner extends Person {

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

    public Set<Pet> getCats() {
        return Sets.filter(getPetsInternal(), new Predicate<Pet>() {
            public boolean apply(Pet pet) { 
                return pet.getType().getName().equals("cat")
            }
        });         
    }
}

Which you could also do inside your parsePets method and annotate it with @PostLoad so that that method would be invoked after the owner whas retrieved from the database.

这篇关于添加两个变量后的BeanCreationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆