2015-11-02 63 views
1

我有以下的模型實體:JPA庫org.hibernate.LazyInitializationException:無法初始化代理 - 沒有會話

@Entity 
@Table(name="ABONADO_IMEI") 
public class SubscriberImei { 
    private SubscriberImeiId id; 
    private Terminal terminal; 
    private String state; 
    private Date date; 

    @EmbeddedId 
    public SubscriberImeiId getId() { 
     return id; 
    } 
    public void setId(SubscriberImeiId id) { 
     this.id = id; 
    } 

    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="ID_TERMINAL", nullable=false) 
    public Terminal getTerminal() { 
     return terminal; 
    } 
    public void setTerminal(Terminal terminal) { 
     this.terminal = terminal; 
    } 

    @Column(name="Estado") 
    public String getState() { 
     return state; 
    } 
    public void setState(String state) { 
     this.state = state; 
    } 

    @Column(name="Fecha") 
    public Date getDate() { 
     return date; 
    } 
    public void setDate(Date date) { 
     this.date = date; 
    } 

} 

@Entity() 
public class Terminal { 
    private long id; 
    private String code; 
    private String brand; 
    private String model; 
    private String services; 
    private Set<SubscriberImei> subscriberImei; 

    public Terminal(){ 

    } 

    @Id 
    @SequenceGenerator(name="SEQ_TERMINAL_ID", sequenceName="SEQ_TERMINAL_ID",allocationSize=1) 
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator = "SEQ_TERMINAL_ID") 
    public long getId() { 
     return id; 
    } 

    public void setId(long id) { 
     this.id = id; 
    } 

    @Column(name="Codigo") 
    public String getCode() { 
     return code; 
    } 

    public void setCode(String code) { 
     this.code = code; 
    } 

    @Column(name="Marca") 
    public String getBrand() { 
     return brand; 
    } 

    public void setBrand(String brand) { 
     this.brand = brand; 
    } 

    @Column(name="Modelo") 
    public String getModel() { 
     return model; 
    } 

    public void setModel(String model) { 
     this.model = model; 
    } 

    @Column(name="Servicios") 
    public String getServices() { 
     return services; 
    } 

    public void setServices(String services) { 
     this.services = services; 
    } 

    @OneToMany(fetch=FetchType.LAZY , mappedBy="terminal") 
    public Set<SubscriberImei> getSubscriberImei() { 
     return subscriberImei; 
    } 
    public void setSubscriberImei(Set<SubscriberImei> terminals) { 
     this.subscriberImei = terminals; 
    } 
} 

而且我用下面JPARepository訪問它:

public interface SubscriberImeiDao extends JpaRepository<SubscriberImei, SubscriberImeiId>{ 
    @Query("select u from SubscriberImei u where u.id.snb = ?1 and u.state = ?2") 
    SubscriberImei findBySnbAndState(String snb, String state); 
} 

我需要返回findBySnbAndState的結果。這是我的代碼:

@Transactional 
public SubscriberImei imeiQuery(String countryId, String snb) { 
    SubscriberImei subs = null; 

    try{ 
     this.validateRegion(countryId, snb); 

     subs = this.getSubscriberDao().findBySnbAndState(snb,"A"); 
     subs.getTerminal().getBrand(); 
     if(subs != null) 
      log.info("Subscriber found {}", subs); 
     else 
      log.info("Subcriber not found!"); 
    } catch (Exception ex) { 
     log.error("Unknown Exception -- ", ex); 
    } 
    return subs; 
} 

和我得到的線subs.getTerminal()所提到的例外getBrand()。有了這條線,我迫使懶惰的關係被遵循(如其他一些問題中所建議的)。我還添加以下行到我的上下文:

<tx:annotation-driven mode="aspectj"/> 

改變FetchType躍躍欲試使得它的工作,但我不想這樣做,因爲沒有必要總是遵循的關係。我錯過了什麼?我究竟做錯了什麼?

感謝

這是完整的異常堆棧跟蹤

org.hibernate.LazyInitializationException: could not initialize proxy - no Session 
    at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:165) 
    at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:286) 
    at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:185) 
    at ar.com.redmondsoftware.imeitracking.model.Terminal_$$_jvste48_0.getBrand(Terminal_$$_jvste48_0.java) 
    at ar.com.redmondsoftware.imeitrackingbusinesslogic.service.impl.ImeiQueryImpl.imeiQuery(ImeiQueryImpl.java:24) 
    at ar.com.redmondsoftware.imeitracking.QueryImei.testQueryImei(QueryImei.java:34) 
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) 
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) 
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) 
    at java.lang.reflect.Method.invoke(Method.java:606) 
    at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50) 
    at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12) 
    at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47) 
    at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17) 
    at org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26) 
    at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78) 
    at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57) 
    at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290) 
    at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71) 
    at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288) 
    at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58) 
    at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268) 
    at org.junit.runners.ParentRunner.run(ParentRunner.java:363) 
    at org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50) 
    at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:467) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:683) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:390) 
    at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:197) 

回答

1

如果你不希望它急於取回所有的時間,你可以做一個不同的查詢,做熱切需要的時候取:

@Query("SELECT u FROM SubscriberImei u LEFT JOIN FETCH u.terminal WHERE u.id.snb = ?1 and u.state = ?2") 
SubscriberImei findBySnbAndStateWithTerminal(String snb, String state); 

此查詢幾乎總是首選,因爲它會用一個查詢而不是兩個來加載數據。

+0

它的作品,很棒的主意!謝謝。但是你知道爲什麼@Transactional aproach不起作用嗎? – Diego

+0

我不能說沒有看到更多的代碼。你使用spring Transactional而不是javax?庫如何注入? – teacurran

+0

我們正在使用「org.springframework.transaction.annotation.Transactional」,這是我們注入存儲庫的方式:「」 – Diego

相關問題