21

I use spring-data-jpa with spring-boot(v2.0.0.RELEASE), I just wrote a CRUD demo on MySQL, but an exception occurs during runtime, source code as follows:

Source code

User.java

@Entity
public class User implements Serializable {
    private static final long serialVersionUID = 1L;

    @Id
    private Integer id;
    private String username;
    private String password;

    ...getter&setter
} 

UserRepository.java

public interface UserRepository extends JpaRepository<User, Integer> {

}

UserServiceTest.java

@RunWith(SpringRunner.class)
@SpringBootTest
public class UserServiceTest {

    @Autowired
    private UserRepository userRepository;

    @Test
    public void getUserById() throws Exception{
        userRepository.getOne(1);
    }

}

application.yml

spring:
  datasource:
    username: ***
    password: ***
    driver-class-name: com.mysql.jdbc.Driver
    url: ********
  thymeleaf:
    cache: false
  jpa:
    show-sql: true
    hibernate:
      ddl-auto: update

Exception details

org.hibernate.LazyInitializationException: could not initialize proxy - no Session

at org.hibernate.proxy.AbstractLazyInitializer.initialize(AbstractLazyInitializer.java:155)
at org.hibernate.proxy.AbstractLazyInitializer.getImplementation(AbstractLazyInitializer.java:268)
at org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer.invoke(JavassistLazyInitializer.java:73)
at cn.shuaijunlan.sdnsecuritysystem.domain.po.User_$$_jvstc90_0.getUsername(User_$$_jvstc90_0.java)
at cn.shuaijunlan.sdnsecuritysystem.service.UserServiceTest.getUserById(UserServiceTest.java:33)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
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)

I try to another method userRepository.findOne(1), it can run successfully.

2
  • Try to add @Transactional to your test method... Commented Apr 18, 2018 at 9:22
  • 1
    @Cepr0 Add @Transactional to the unit test method, it can run successfully, can you give more details about why it can run without exception? Commented Apr 18, 2018 at 10:50

4 Answers 4

32

You can add @Transactional annotation to your test method to avoid this exception.

Method getOne return the 'reference' (proxy) of the entity which properties can be lazy loaded. See it code - it uses getReference method of EntityManager. From it javadoc:

Get an instance, whose state may be lazily fetched.

In Spring the implementation of EntityManager is org.hibernate.internal.SessionImpl - so without the Session the Spring can not get this method.

To have a session you can just create a transaction...

Sign up to request clarification or add additional context in comments.

4 Comments

But if my test uses the @Transactional annotation, doesn't that mean the test is only valid for transactional queries?
@MiguelMunoz every method in JpaRepository is transactional
In my case, adding @Transactional to the service itself helped
But why is it helpful at this point? Does the @Transaction annotation create a session? AFAIK this annotation handle rollback things but maybe my knowledge isn't enough.
4

Your test should be like this:

@RunWith(SpringRunner.class)    


@SpringBootTest
@Transactional    

public class QuestionTesting {   

    @Test    
    public void test() {    

    }    
}    

1 Comment

Please try to use code block formatting on all the code in your answer. stackoverflow.com/editing-help#code
4

just add in application properties spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true

2 Comments

Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center.
A couple of recommendations not to do this... thorben-janssen.com/lazyinitializationexception and vladmihalcea.com/… - more discussion on this answer: stackoverflow.com/a/38690930/444738
-2

In the service class please add a setter for entity manager by using the annoattion @PersistenceContext. To be specific, use

 @PersistenceContext(type = PersistenceContextType.EXTENDED)

In this way, you can access lazy property.

3 Comments

Your example would be more helpful if you included whatever it is you're annotating. Do I apply this to the class? And what do you mean by "the service class"?
Service class is the class having the @Service annotation. I assume you knoe spring containers and spring classes.
The question does not have a service class.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.