web-dev-qa-db-fra.com

LazyInitializationException: impossible d'initialiser le proxy - pas de session

J'utilise spring-data-jpa avec spring-boot(v2.0.0.RELEASE), il suffit d'écrire une démo CURD sur MySQL, mais une exception se produit pendant l'exécution, le code source est le suivant: 

Code source  

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

Détails d'exception

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)

J'essaye à une autre méthode userRepository.findOne(1), elle peut fonctionner avec succès.

3
Shuai Junlan

Vous pouvez ajouter une annotation @Transactional à votre méthode de test pour éviter cette exception.

La méthode getOne renvoie la "référence" (proxy) de l'entité dont les propriétés peuvent être chargées paresseux. Voir code - il utilise la méthode getReference de EntityManager. De cela javadoc:

Obtenez une instance dont l'état peut être récupéré paresseusement.

Au printemps, l'implémentation de EntityManager est org.hibernate.internal.SessionImpl - donc sans la session, le printemps ne peut pas obtenir cette méthode.

Pour avoir une session, vous pouvez simplement créer une transaction ...

6
Cepr0

Dans la classe de service, ajoutez un séparateur pour le gestionnaire d'entités en utilisant l'annotation @PersistenceContext Pour être précis, utilisez

 @PersistenceContext(type = PersistenceContextType.EXTENDED)

De cette façon, vous pouvez accéder à la propriété paresseuse.

0
KayV