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.
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 ...
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.