2012-10-18 15 views
5

के भीतर हाइबरनेट सत्र मुझे वसंत सत्र कारखाने के साथ हाइबरनेट में अनामिक आंतरिक कक्षा पर सत्र प्राप्त करने में कोई समस्या है। यहाँ कोड है:आंतरिक कक्षा

public class DomainDaoImpl extends BasicDaoImpl<Domain> implements Iterable<Collection<Domain>> { 

... 

@Override 
public Iterator<Collection<Domain>> iterator() { 
    return (new Iterator<Collection<Domain>>() { 
     private int counter = 0; 
     public static final int LIMIT = 100; 

     ... 

     @Override 
     @Transactional(readOnly = true) 
     public Collection<Domain> next() { 
      final Criteria criteria = getCurrentSession().createCriteria(Domain.class); 
      final LinkedHashSet<Domain> result = new LinkedHashSet<Domain>(); 

      List resultList = null; 
      while (!(resultList = criteria.list()).isEmpty()) { 
       criteria.setFirstResult((counter++ * LIMIT) + 1); 
       criteria.setMaxResults(LIMIT); 
       result.addAll(resultList); 
      } 
      return result; 
     } 

     ... 
    }); 

मुद्दा org.hibernate.HibernateException है: नहीं सत्र वर्तमान धागा के लिए मिला यह आम तौर पर होता है जब डीएओ विधि लेन-देन के भीतर नहीं है। तो इसे एक आंतरिक कक्षा के साथ कैसे काम करना है?

उत्तर

1

मुझे लगता है कि आंतरिक कक्षा स्तर पर @Transactional(readOnly = true) परिभाषित करना, वसंत इस पर लेनदेन पहलू का पता लगाने और लागू करने में सक्षम नहीं होगा। तो यह निश्चित रूप से काम नहीं करेगा।

लेकिन मुझे लगता है कि अगर आप नीचे दिए की तरह कुछ लिखने काम कर सकते हैं% नहीं 100 यकीन है कि (i शक एक बार आप आह्वान इटरेटर विधि लेन-देन बंद कर दिया है)

@Override 
@Transactional(readOnly = true) 
public Iterator<Collection<Domain>> iterator() { 
... 
} 

एक और विकल्प फोन करने वाले लेन-देन के लिए जिम्मेदार हो या लिखने जाने जा सकती है रैपर विधि iterator()getAllDomain() पर और उस विधि को लेनदेन लागू करें।

समाधान काम जो (टिप्पणी में उल्लेख किया है)

हो सकता है आप sessionFactory से getCurrentSession() getCurrentSession की तरह() में कुछ पैच कर सकते हैं नहीं तो उपलब्ध तो openSession (उपयोग करें), बिल्कुल आप करने के लिए है नया सत्र खोला गया तो इसे मैन्युअल रूप से बंद करें।

+0

प्रतिक्रिया के लिए धन्यवाद, मैंने सफलता के बिना पूछने से पहले इसे आजमाया है। और मैं नहीं चाहता कि लेनदेन लेनदेन प्रबंधन के लिए जिम्मेदार हो क्योंकि मैं अपनी सेवा परत में @ ट्रांसेक्शनल नहीं चाहता हूं। –

+1

हो सकता है कि आप सत्र से प्राप्त करने के लिए 'getCurrentSession() जैसे getCurrentSession() में कुछ पैच कर सकते हैं यदि उपलब्ध नहीं है तो' ओपन सत्र() 'का उपयोग करें, अगर आपको नया सत्र खोला जाता है तो आपको इसे मैन्युअल रूप से बंद करना होगा। –

+0

यह काम करता है :-) वैसे भी, चलो देखते हैं कि कोई और सुझाव है –

1

आप लोड समय पहलू बुनाई

यहाँ बुनियादी उदाहरण है यह

स्प्रिंग संदर्भ

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xmlns:context="http://www.springframework.org/schema/context" 
    xmlns:tx="http://www.springframework.org/schema/tx" 
    xmlns:jdbc="http://www.springframework.org/schema/jdbc" 
     xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.1.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.1.xsd http://www.springframework.org/schema/jdbc http://www.springframework.org/schema/jdbc/spring-jdbc.xsd"> 

    <context:component-scan base-package="org.foo.bar" /> 
    <context:annotation-config /> 
    <context:load-time-weaver /> 

    <tx:annotation-driven mode="aspectj" proxy-target-class="true"/> 

    <jdbc:embedded-database id="dataSource"> 
     <jdbc:script location="classpath:schema.sql"/> 
    </jdbc:embedded-database> 

    <bean id="sessionFactory" class="org.springframework.orm.hibernate4.LocalSessionFactoryBean"> 
     <property name="dataSource" ref="dataSource"/> 
     <property name="annotatedClasses"> 
      <list> 
       <value>org.foo.bar.MyEntity</value> 
      </list> 
     </property> 
    </bean> 

    <bean id="transactionManager" class="org.springframework.orm.hibernate4.HibernateTransactionManager"> 
     <property name="sessionFactory" ref="sessionFactory"/> 
    </bean> 

</beans> 

इकाई वर्ग

कैसे करना कॉन्फ़िगर कर सकते हैं

पैकेज org.foo.bar;

import javax.persistence.Entity; 
import javax.persistence.Id; 
import javax.persistence.Table; 

@Entity 
@Table(name = "ENTITY") 
public class MyEntity { 

    @Id 
    private long id; 
    private String name; 

    public long getId() { 
     return id; 
    } 

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

    public String getName() { 
     return name; 
    } 

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

    @Override 
    public String toString() { 
     final StringBuilder sb = new StringBuilder(); 
     sb.append("MyEntity"); 
     sb.append("{id=").append(id); 
     sb.append(", name='").append(name).append('\''); 
     sb.append('}'); 
     return sb.toString(); 
    } 
} 

दाव वर्ग

पैकेज org.foo.bar;

import org.hibernate.Criteria; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.stereotype.Component; 
import org.springframework.transaction.annotation.Transactional; 

import java.util.Iterator; 
import java.util.NoSuchElementException; 

@Component 
public class MyEntityDao implements Iterable<MyEntity> { 

    @Autowired 
    private SessionFactory sessionFactory; 

    @Override 
    public Iterator<MyEntity> iterator() { 
     return new Iterator<MyEntity>() { 
      private int num = 0; 
      private MyEntity item; 

      @Override 
      @Transactional(readOnly = true) 
      public boolean hasNext() { 
       item = getEntity(); 
       return item != null; 
      } 

      @Override 
      @Transactional(readOnly = true) 
      public MyEntity next() { 
       try { 
        if(item == null) { 
         item = getEntity(); 
         if(item == null) { 
          throw new NoSuchElementException(); 
         } 
        } 
        return item; 
       } finally { 
        item = null; 
       } 
      } 

      @Override 
      public void remove() { 
       throw new UnsupportedOperationException(); 
      } 

      private MyEntity getEntity() { 
       final Criteria criteria = getCurrentSession().createCriteria(MyEntity.class); 
       criteria.setFirstResult(num++); 
       criteria.setMaxResults(1); 
       return (MyEntity) criteria.uniqueResult(); 
      } 
     }; 
    } 

    public Session getCurrentSession() { 
     return sessionFactory.getCurrentSession(); 
    } 
} 

एसक्यूएल

drop table ENTITY if exists 

create table ENTITY (id bigint generated by default as identity (start with 1), name varchar(255), primary key (id)) 

insert into ENTITY (name) values ('Entity1') 
insert into ENTITY (name) values ('Entity2') 
insert into ENTITY (name) values ('Entity3') 

यूनिट परीक्षण

पैकेज org.foo।बार;

import org.junit.Test; 
import org.junit.runner.RunWith; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.test.context.ContextConfiguration; 
import org.springframework.test.context.junit4.SpringJUnit4ClassRunner; 

import static org.junit.Assert.assertEquals; 

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations = { 
    "classpath:applicationContext.xml" 
}) 
public class MyEntityDaoTest { 

    @Autowired 
    private MyEntityDao dao; 

    @Test 
    public void testDao() throws Exception { 
     int count = 0; 
     for(MyEntity a : dao) { 
      count++; 
     } 
     assertEquals(3, count); 
    } 

} 

यहाँ मेरी pom.xml है http://maven.apache.org/xsd/maven-4.0.0.xsd "> 4.0.0

<groupId>org.foo.bar</groupId> 
    <artifactId>spring-aspectj-hibernate</artifactId> 
    <version>1.0</version> 

    <properties> 
     <spring.version>3.1.1.RELEASE</spring.version> 
    </properties> 

    <dependencies> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-aspects</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-orm</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-instrument</artifactId> 
      <version>${spring.version}</version> 
     </dependency> 
     <dependency> 
      <groupId>org.springframework</groupId> 
      <artifactId>spring-test</artifactId> 
      <version>${spring.version}</version> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>org.aspectj</groupId> 
      <artifactId>aspectjweaver</artifactId> 
      <version>1.6.12</version> 
     </dependency> 

     <dependency> 
      <groupId>org.hibernate</groupId> 
      <artifactId>hibernate-entitymanager</artifactId> 
      <version>4.1.1.Final</version> 
     </dependency> 

     <dependency> 
      <groupId>org.hsqldb</groupId> 
      <artifactId>hsqldb</artifactId> 
      <version>1.8.0.10</version> 
      <scope>test</scope> 
     </dependency> 

     <dependency> 
      <groupId>junit</groupId> 
      <artifactId>junit</artifactId> 
      <version>4.10</version> 
      <scope>test</scope> 
     </dependency> 

    </dependencies> 

</project> 

इसके बाद आपको निम्नलिखित तर्क -javaagent:<PATH-TO>/spring-instrument-{vertion}.jar के साथ JVM चलाने के लिए है। -javaagent जोड़ने से रोकने के लिए आपको तर्क पहलू संकलन-समय बुनाई भी कॉन्फ़िगर कर सकते हैं।

संबंधित मुद्दे