添加两个变量后BeanCreationException

有人可以告诉我如何通过BeanCreationException?

在向Owner.java添加两个变量后,我得到一个BeanCreationException ,如下所示:

@OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER) private Set pets; //I added the following two variable declarations @Transient private Set cats = new HashSet(); @Transient private Set dogs = new HashSet(); 

我还为猫和狗添加了getter和setter方法,以及将猫和狗作为宠物子集填充的方法,如下所示:

 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 getPetsInternal() { if (this.pets == null) {this.pets = new HashSet();} return this.pets; } 

当我执行Run As时,应用程序无法初始化…在eclipse中运行在服务器上,并提供以下错误消息:

 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)] 

这是business-config.xml的代码 。

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

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

根据axiopisty的要求,除了添加猫和狗之外,我无法评论所有内容,因为从OwnerController.java调用宠物,猫和狗,如下所示:

 @RequestMapping(value = "/owners", method = RequestMethod.GET) public String processFindForm(@RequestParam("ownerID") String ownerId, Owner owner, BindingResult result, Map model) { Collection 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"; } 

编辑:

根据Sotirios的请求,这是我的实体类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 pets; //I added next two variables @Transient @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER) private Set cats = new HashSet(); @Transient @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER) private Set dogs = new HashSet(); //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 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 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 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 getPetsInternal() { if (this.pets == null) {this.pets = new HashSet();} return this.pets; } public List getPets() { List sortedPets = new ArrayList(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(); } } 

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

 @Entity @Table(name = "owners") public class Owner extends Person { @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER) private Set pets; public Set getCats() { Set cats = new HashSet(); for (Pet pet : getPetsInternal()) { if (pet.getType().getName().equals("cat")) { cats.add(pet); } } return cats; } } 

缺点是每次需要时都会重新创建集合。 您可以使用Google Guava之类的内容轻松完成此操作并创建filter列表。

 @Entity @Table(name = "owners") public class Owner extends Person { @OneToMany(cascade = CascadeType.ALL, mappedBy = "owner", fetch=FetchType.EAGER) private Set pets; public Set getCats() { return Sets.filter(getPetsInternal(), new Predicate() { public boolean apply(Pet pet) { return pet.getType().getName().equals("cat") } }); } } 

您也可以在parsePets方法中执行此操作,并使用@PostLoad对其进行注释,以便在所有者从数据库中检索后调用该方法。

我建议你可以在你的实体中使用@Access(AccessType.FIELD),它可能会解决问题。