2012-12-02 3 views
1

하나의 특정 메소드에 대해 초기화하려고하는 일부 게으른로드 속성이있는 엔티티가 있습니다. 대부분로드 시간이 너무 길기 때문에로드 할 수 없습니다. EAGER로 설정).Hibernate.initialize()가 완전히 무시되었습니다.

이러한 속성 중 하나는 컬렉션이며 Hibernate.initialize()를 호출 할 때 아름답게로드됩니다. 다른 하나는 하나의 객체이고 내가 시도한 것에 관계없이로드되지 않습니다. 개체의 ID 자체를 사용할 수 없기 때문에 심지어 같은 세션에서조차도 쿼리 할 수 ​​없습니다.

initialize()를 호출 할 때 예외가 없으므로 무시되는 것입니다. 로그에는 컬렉션에서이 객체를 호출 할 때 대응하는 쿼리가 표시되지만 단일 객체에서는 호출되지 않습니다. 이 속성 (기기)을로드하는 데 도움을 주시면 대단히 감사하겠습니다. 다음 코드입니다 :

EDIT 데이터베이스에 외래 키가 없습니다. 일단이 문제를 해결하면 가져 오기 쿼리가 콘솔에 나타나지만 Device 객체는 initialize()가 완료된 후에도 여전히 프록시입니다. 나는이 작업을 수행하여 해결 해낸 : 나는 다른 객체에 속성을 복사하는 경우

Device device = new Device(); 
     device.setIdDevice(surveyLog.getDevice().getIdDevice()); 
     device.setName(surveyLog.getDevice().getName()); 
     surveyLog.setDevice(device); 

, 그들은이 방법 밖에 액세스 할 수 있습니다, 그렇지 않으면 객체가 프록시 남아있다. 이걸 일으킬 수있는 어떤 생각? 프록시에 필드의 이름을 '액세스 할 수 있기 때문에

import static javax.persistence.GenerationType.IDENTITY; 

import java.math.BigDecimal; 
import java.sql.Timestamp; 
import java.util.ArrayList; 
import java.util.List; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.OneToMany; 
import javax.persistence.Table; 

import org.hibernate.annotations.Cascade; 
import org.hibernate.annotations.CascadeType; 
import org.hibernate.annotations.Fetch; 
import org.hibernate.annotations.FetchMode; 

import com.google.gson.annotations.Expose; 

@Entity 
@Table(name="SurveyLog") 
public class SurveyLog 
{ 
    // Fields  
    @Expose private Long idSurveyLog; 
    @Expose private Survey survey; 
    @Expose private Device device; 
    @Expose private BigDecimal latitude; 
    @Expose private BigDecimal longitude; 
    @Expose private Timestamp timestamp; 
    @Expose private List<SurveyAnswerLog> surveyAnswers = new ArrayList<SurveyAnswerLog>(); 

    /** 
    * Constructor. 
    * 
    */ 
    public SurveyLog() {} 

    // Property accessors 
    @Id 
    @GeneratedValue(strategy=IDENTITY) 
    @Column(name="idSurveyLog", unique=true, nullable=false) 
    public Long getIdSurveyLog() 
    { 
     return idSurveyLog; 
    } 

    public void setIdSurveyLog(Long idSurveyLog) 
    { 
     this.idSurveyLog = idSurveyLog; 
    } 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="idSurvey", nullable=false) 
    public Survey getSurvey() 
    { 
     return survey; 
    } 

    public void setSurvey(Survey survey) 
    { 
     this.survey = survey; 
    } 

    @ManyToOne(fetch=FetchType.LAZY) 
    @Fetch(value = FetchMode.SELECT) 
    @JoinColumn(name="idDevice", nullable=false)  
    public Device getDevice() 
    { 
     return device; 
    } 

    public void setDevice(Device device) 
    { 
     this.device = device; 
    } 

    @Column(name="latitude", precision=8, scale=6) 
    public BigDecimal getLatitude() 
    { 
     return latitude; 
    } 

    public void setLatitude(BigDecimal latitude) 
    { 
     this.latitude = latitude; 
    } 

    @Column(name="longitude", precision=9, scale=6) 
    public BigDecimal getLongitude() 
    { 
     return longitude; 
    } 

    public void setLongitude(BigDecimal longitude) 
    { 
     this.longitude = longitude; 
    } 

    @Column(name="timestamp", length=19) 
    public Timestamp getTimestamp() 
    { 
     return timestamp; 
    } 

    public void setTimestamp(Timestamp timestamp) 
    { 
     this.timestamp = timestamp; 
    } 

    @OneToMany(fetch=FetchType.LAZY, mappedBy="surveyLog") 
    @Cascade({CascadeType.ALL, CascadeType.DELETE_ORPHAN}) 
    public List<SurveyAnswerLog> getSurveyAnswers() 
    { 
     return surveyAnswers; 
    } 

    public void setSurveyAnswers(List<SurveyAnswerLog> surveyAnswers) 
    { 
     this.surveyAnswers = surveyAnswers; 
    } 
} 



import static javax.persistence.GenerationType.IDENTITY; 

import java.util.EnumSet; 
import java.util.HashMap; 
import java.util.Map; 

import javax.persistence.Column; 
import javax.persistence.Entity; 
import javax.persistence.FetchType; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.Table; 
import javax.persistence.UniqueConstraint; 
import javax.persistence.Version; 

import com.google.gson.annotations.Expose; 
import com.sitei.base.model.City; 
import com.sitei.base.model.Company; 

@Entity 
@Table(name="Device", uniqueConstraints = @UniqueConstraint(columnNames = "macAddress")) 
public class Device 
{ 
    // Fields 
    @Expose private Integer idDevice; 
    @Expose private String macAddress; 
    @Expose private String name; 
    @Expose private String description; 
    @Expose private Short type; 
    @Expose private City city; 
    @Expose private Company company; 
    @Expose private Survey survey; 
    @Expose private Integer surveyPoints; 
    @Expose private boolean active; 
    @Expose private Long version; 



    /** 
    * Constructor. 
    * 
    */ 
    public Device() {} 

    // Property accessors 
    @Id 
    @GeneratedValue(strategy=IDENTITY) 
    @Column(name="idDevice", unique=true, nullable=false) 
    public Integer getIdDevice() 
    { 
     return idDevice; 
    } 

    public void setIdDevice(Integer idDevice) 
    { 
     this.idDevice = idDevice; 
    } 

    @Column(name="macAddress", nullable=false, length=17) 
    public String getMacAddress() 
    { 
     return macAddress; 
    } 

    public void setMacAddress(String macAddress) 
    { 
     this.macAddress = macAddress; 
    } 

    @Column(name="name", nullable=false, length=64) 
    public String getName() 
    { 
     return name; 
    } 

    public void setName(String name) 
    { 
     this.name = name; 
    } 

    @Column(name="description", length=256) 
    public String getDescription() 
    { 
     return description; 
    } 

    public void setDescription(String description) 
    { 
     this.description = description; 
    } 

    @Column(name="type", nullable=false) 
    public Short getType() 
    { 
     return type; 
    } 

    public void setType(Short type) 
    { 
     this.type = type; 
    } 

    @ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumn(name="idCity", nullable=false) 
    public City getCity() 
    { 
     return city; 
    } 

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

    @ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumn(name="idCompany") 
    public Company getCompany() 
    { 
     return company; 
    } 

    public void setCompany(Company company) 
    { 
     this.company = company; 
    } 

    @ManyToOne(fetch=FetchType.EAGER) 
    @JoinColumn(name="idSurvey") 
    public Survey getSurvey() 
    { 
     return survey; 
    } 

    public void setSurvey(Survey survey) 
    { 
     this.survey = survey; 
    } 

    @Column(name="surveyPoints", nullable=false) 
    public Integer getSurveyPoints() 
    { 
     return surveyPoints; 
    } 

    public void setSurveyPoints(Integer surveyPoints) 
    { 
     this.surveyPoints = surveyPoints; 
    } 

    @Column(name="active", nullable=false) 
    public boolean isActive() 
    { 
     return active; 
    } 

    public void setActive(boolean active) 
    { 
     this.active = active; 
    } 

    @Version 
    public Long getVersion() 
    { 
     return version; 
    } 

    public void setVersion(Long version) 
    { 
     this.version = version; 
    } 
} 

답변

1

분명히 코드가 이미 작동합니다 감사합니다

@Transactional  
public SurveyLog getById(Long id) 
{ 
    SurveyLog surveyLog = this.surveyLogDAO.findById(id); 

    Hibernate.initialize(surveyLog.getDevice()); //doesn't work 
    Hibernate.initialize(surveyLog.getSurveyAnswers()); //works like a charm 
    return surveyLog; 
} 

그리고이 내 매핑합니다. 프록시를 기본 객체로 대체해야하는 이유는 무엇입니까? 나는 초기화가 그 프록시 뒤에 실제 객체를 두는 것 이상을 의미한다는 절전 문서에서 어떤 힌트도 발견하지 못했다.

Hibernate는 아마도 프록시에 대한 참조를 유효하게 유지하기 위해 프록시를 버리지 않을 것이다. 주석 섹션의 링크에서 설명한대로 프록시에서 구현을 가져올 수 있습니다.

+0

반환 할 객체가 나중에 JSON으로 직렬화되고 해당 속성의 데이터에 액세스 할 수있게하려면 다른 객체에 수동으로 복사해야합니다. 어떤 이유로이 작업은 컬렉션에서 다르게 작동합니다. 이 경우 초기화를 수행하면 객체의 속성이 자동으로로드되므로 객체 복제의 지루함이 제거됩니다. – JayPea

+0

리플렉션을 사용하여 JSON 변환을 완료 했습니까? 인터페이스 구현 방식을 시도해보십시오. Hibernate는 항상 게으른 일대일 관계에 대해 프록시를 사용한다. 1 대 다수의 경우 사용자 정의 컬렉션 클래스를 사용할 수 있습니다. – sorencito

+1

https://forum.hibernate.org/viewtopic.php?t=947035 – sorencito

관련 문제