[SPRING] 두 변수를 추가 한 후 BeanCreationException 발생
SPRING두 변수를 추가 한 후 BeanCreationException 발생
누군가 BeanCreationException을 지나치게하는 법을 보여줄 수 있습니까?
다음과 같이 Owner.java에 두 개의 변수를 추가 한 후 BeanCreationException이 발생합니다.
@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>();
나는 고양이와 개를위한 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<Pet> getPetsInternal() {
if (this.pets == null) {this.pets = new HashSet<Pet>();}
return this.pets;
}
응용 프로그램을 실행할 때 초기화 실패 ... 이클립스 내에서 서버에서 실행 및 다음과 같은 오류 메시지가 있습니다 :
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<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>();
Axiopisty의 요청에 따라 애완 동물, 고양이, 개가 다음과 같이 OwnerController.java에서 호출되기 때문에 고양이와 개를 제외하고는 모든 것을 주석으로 처리 할 수 없습니다.
@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";
}
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<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();
}
}
해결법
-
==============================
1.왜 분리 된리스트는 인스턴스 변수 여야 만합니까? 단순히 getCats 메서드 (및 기타)를 만들고 단순히 애완 동물 컬렉션을 필터링하지 않는 것이 어떻습니까? 모든 것을 맵핑하려고하면 imho가 지나치게 복잡해집니다.
왜 분리 된리스트는 인스턴스 변수 여야 만합니까? 단순히 getCats 메서드 (및 기타)를 만들고 단순히 애완 동물 컬렉션을 필터링하지 않는 것이 어떻습니까? 모든 것을 맵핑하려고하면 imho가 지나치게 복잡해집니다.
@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; } }
단점은 컬렉션이 필요할 때마다 재생성된다는 것입니다. Google Guava와 같은 도구로이 작업을 쉽게 수행하고 필터 목록을 만들 수 있습니다.
@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") } }); } }
parsePets 메소드에서 수행 할 수있는 작업과 @PostLoad 주석을 달아서 소유자가 데이터베이스에서 검색 한 후에 해당 메소드가 호출되도록 할 수 있습니다.
-
==============================
2.엔티티에서 @Access (AccessType.FIELD)를 사용하면 문제가 해결 될 수도 있습니다.
엔티티에서 @Access (AccessType.FIELD)를 사용하면 문제가 해결 될 수도 있습니다.
from https://stackoverflow.com/questions/20307310/beancreationexception-after-adding-two-variables by cc-by-sa and MIT license
'SPRING' 카테고리의 다른 글
[SPRING] 스프링 부트 어떻게 jar 파일 외부의 특성 파일을 읽는가? (0) | 2019.01.25 |
---|---|
[SPRING] 매개 변수 객체 속성 (0) | 2019.01.25 |
[SPRING] 스프링 데이터 Jpa로 멀티 테넌시를 사용하는 방법 (0) | 2019.01.24 |
[SPRING] 봄, 최대 절전 모드 - 다 대다 - LazyInitializationException (0) | 2019.01.24 |
[SPRING] Spring Batch Java Config : 예외가 발생하면 단계를 생략하고 다음 단계로 넘어갑니다. (0) | 2019.01.24 |