휴지 상태 수정 방법초기화예외: 역할 모음을 느리게 초기화하지 못했습니다. 프록시를 초기화할 수 없습니다. 세션 없음
스프링 프로젝트의 커스텀 Authentication Provider에서 로그 사용자의 권한 목록을 읽으려고 하는데 다음 오류가 발생합니다.
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.horariolivre.entity.Usuario.autorizacoes, could not initialize proxy - no Session
at org.hibernate.collection.internal.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:566)
at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:186)
at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:545)
at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:124)
at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:266)
at com.horariolivre.security.CustomAuthenticationProvider.authenticate(CustomAuthenticationProvider.java:45)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:156)
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:177)
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94)
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:211)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:110)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.header.HeaderWriterFilter.doFilterInternal(HeaderWriterFilter.java:57)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.SecurityContextPersistenceFilter.doFilter(SecurityContextPersistenceFilter.java:87)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.context.request.async.WebAsyncManagerIntegrationFilter.doFilterInternal(WebAsyncManagerIntegrationFilter.java:50)
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107)
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:342)
at org.springframework.security.web.FilterChainProxy.doFilterInternal(FilterChainProxy.java:192)
at org.springframework.security.web.FilterChainProxy.doFilter(FilterChainProxy.java:160)
at org.springframework.web.filter.DelegatingFilterProxy.invokeDelegate(DelegatingFilterProxy.java:343)
at org.springframework.web.filter.DelegatingFilterProxy.doFilter(DelegatingFilterProxy.java:260)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:222)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:123)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:502)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:171)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:99)
at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:953)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:408)
at org.apache.coyote.http11.AbstractHttp11Processor.process(AbstractHttp11Processor.java:1023)
at org.apache.coyote.AbstractProtocol$AbstractConnectionHandler.process(AbstractProtocol.java:589)
at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:312)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1145)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:615)
at java.lang.Thread.run(Thread.java:744)
StackOverflow의 다른 토픽을 읽어보면 프레임워크에 의한 이러한 유형의 속성 처리방법에 의해 발생하는 것은 알고 있습니다만, 제 케이스에 대한 해결책을 찾을 수 없습니다.내가 뭘 잘못했는지, 내가 뭘 해야 고칠 수 있는지 누가 알려줄 수 있어?
Custom Authentication Provider의 코드는 다음과 같습니다.
@Component
public class CustomAuthenticationProvider implements AuthenticationProvider {
@Autowired
private UsuarioHome usuario;
public CustomAuthenticationProvider() {
super();
}
@Override
public Authentication authenticate(Authentication authentication) throws AuthenticationException {
System.out.println("CustomAuthenticationProvider.authenticate");
String username = authentication.getName();
String password = authentication.getCredentials().toString();
Usuario user = usuario.findByUsername(username);
if (user != null) {
if(user.getSenha().equals(password)) {
List<AutorizacoesUsuario> list = user.getAutorizacoes();
List <String> rolesAsList = new ArrayList<String>();
for(AutorizacoesUsuario role : list){
rolesAsList.add(role.getAutorizacoes().getNome());
}
List<GrantedAuthority> authorities = new ArrayList<GrantedAuthority>();
for (String role_name : rolesAsList) {
authorities.add(new SimpleGrantedAuthority(role_name));
}
Authentication auth = new UsernamePasswordAuthenticationToken(username, password, authorities);
return auth;
}
else {
return null;
}
} else {
return null;
}
}
@Override
public boolean supports(Class<?> authentication) {
return authentication.equals(UsernamePasswordAuthenticationToken.class);
}
}
마이 엔티티 클래스는 다음과 같습니다.
Usuario Home.java
@Entity
@Table(name = "usuario")
public class Usuario implements java.io.Serializable {
private int id;
private String login;
private String senha;
private String primeiroNome;
private String ultimoNome;
private List<TipoUsuario> tipoUsuarios = new ArrayList<TipoUsuario>();
private List<AutorizacoesUsuario> autorizacoes = new ArrayList<AutorizacoesUsuario>();
private List<DadosUsuario> dadosUsuarios = new ArrayList<DadosUsuario>();
private ConfigHorarioLivre config;
public Usuario() {
}
public Usuario(String login, String senha) {
this.login = login;
this.senha = senha;
}
public Usuario(String login, String senha, String primeiroNome, String ultimoNome, List<TipoUsuario> tipoUsuarios, List<AutorizacoesUsuario> autorizacoesUsuarios, List<DadosUsuario> dadosUsuarios, ConfigHorarioLivre config) {
this.login = login;
this.senha = senha;
this.primeiroNome = primeiroNome;
this.ultimoNome = ultimoNome;
this.tipoUsuarios = tipoUsuarios;
this.autorizacoes = autorizacoesUsuarios;
this.dadosUsuarios = dadosUsuarios;
this.config = config;
}
public Usuario(String login, String senha, String primeiroNome, String ultimoNome, String tipoUsuario, String[] campos) {
this.login = login;
this.senha = senha;
this.primeiroNome = primeiroNome;
this.ultimoNome = ultimoNome;
this.tipoUsuarios.add(new TipoUsuario(this, new Tipo(tipoUsuario)));
for(int i=0; i<campos.length; i++)
this.dadosUsuarios.add(new DadosUsuario(this, null, campos[i]));
}
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "login", nullable = false, length = 16)
public String getLogin() {
return this.login;
}
public void setLogin(String login) {
this.login = login;
}
@Column(name = "senha", nullable = false)
public String getSenha() {
return this.senha;
}
public void setSenha(String senha) {
this.senha = senha;
}
@Column(name = "primeiro_nome", length = 32)
public String getPrimeiroNome() {
return this.primeiroNome;
}
public void setPrimeiroNome(String primeiroNome) {
this.primeiroNome = primeiroNome;
}
@Column(name = "ultimo_nome", length = 32)
public String getUltimoNome() {
return this.ultimoNome;
}
public void setUltimoNome(String ultimoNome) {
this.ultimoNome = ultimoNome;
}
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "tipo_usuario", joinColumns = { @JoinColumn(name = "fk_usuario") }, inverseJoinColumns = { @JoinColumn(name = "fk_tipo") })
@LazyCollection(LazyCollectionOption.TRUE)
public List<TipoUsuario> getTipoUsuarios() {
return this.tipoUsuarios;
}
public void setTipoUsuarios(List<TipoUsuario> tipoUsuarios) {
this.tipoUsuarios = tipoUsuarios;
}
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "autorizacoes_usuario", joinColumns = { @JoinColumn(name = "fk_usuario") }, inverseJoinColumns = { @JoinColumn(name = "fk_autorizacoes") })
@LazyCollection(LazyCollectionOption.TRUE)
public List<AutorizacoesUsuario> getAutorizacoes() {
return this.autorizacoes;
}
public void setAutorizacoes(List<AutorizacoesUsuario> autorizacoes) {
this.autorizacoes = autorizacoes;
}
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "dados_usuario", joinColumns = { @JoinColumn(name = "fk_usuario") }, inverseJoinColumns = { @JoinColumn(name = "fk_dados") })
@LazyCollection(LazyCollectionOption.TRUE)
public List<DadosUsuario> getDadosUsuarios() {
return this.dadosUsuarios;
}
public void setDadosUsuarios(List<DadosUsuario> dadosUsuarios) {
this.dadosUsuarios = dadosUsuarios;
}
@OneToOne
@JoinColumn(name="fk_config")
public ConfigHorarioLivre getConfig() {
return config;
}
public void setConfig(ConfigHorarioLivre config) {
this.config = config;
}
}
Autorizacoes Usuario.자바
@Entity
@Table(name = "autorizacoes_usuario", uniqueConstraints = @UniqueConstraint(columnNames = "id"))
public class AutorizacoesUsuario implements java.io.Serializable {
private int id;
private Usuario usuario;
private Autorizacoes autorizacoes;
public AutorizacoesUsuario() {
}
public AutorizacoesUsuario(Usuario usuario, Autorizacoes autorizacoes) {
this.usuario = usuario;
this.autorizacoes = autorizacoes;
}
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@OneToOne
@JoinColumn(name = "fk_usuario", nullable = false, insertable = false, updatable = false)
public Usuario getUsuario() {
return this.usuario;
}
public void setUsuario(Usuario usuario) {
this.usuario = usuario;
}
@OneToOne
@JoinColumn(name = "fk_autorizacoes", nullable = false, insertable = false, updatable = false)
public Autorizacoes getAutorizacoes() {
return this.autorizacoes;
}
public void setAutorizacoes(Autorizacoes autorizacoes) {
this.autorizacoes = autorizacoes;
}
}
오토리자코자바
@Entity
@Table(name = "autorizacoes")
public class Autorizacoes implements java.io.Serializable {
private int id;
private String nome;
private String descricao;
public Autorizacoes() {
}
public Autorizacoes(String nome) {
this.nome = nome;
}
public Autorizacoes(String nome, String descricao) {
this.nome = nome;
this.descricao = descricao;
}
@Id
@Column(name = "id", unique = true, nullable = false)
@GeneratedValue(strategy=GenerationType.AUTO)
public int getId() {
return this.id;
}
public void setId(int id) {
this.id = id;
}
@Column(name = "nome", nullable = false, length = 16)
public String getNome() {
return this.nome;
}
public void setNome(String nome) {
this.nome = nome;
}
@Column(name = "descricao", length = 140)
public String getDescricao() {
return this.descricao;
}
public void setDescricao(String descricao) {
this.descricao = descricao;
}
}
github에서 전체 프로젝트 이용 가능
--> https://github.com/klebermo/webapp_horario_livre
하다, 하다, 하다, 하다, 하다를 요.fetch=FetchType.EAGER
ManyToMany many many many many many many many many many many many many many many many many 。
@ManyToMany(fetch = FetchType.EAGER)
스프링 컨피규레이션파일에 다음 항목을 추가하여 스프링트랜잭션 매니저를 실장하는 것이 좋습니다.
<bean id="transactionManager"
class="org.springframework.orm.hibernate4.HibernateTransactionManager">
<property name="sessionFactory" ref="sessionFactory" />
</bean>
<tx:annotation-driven />
다음으로 다음과 같이 인증방식에 @Transactional 주석을 추가할 수 있습니다.
@Transactional
public Authentication authenticate(Authentication authentication)
그러면 인증 메서드 기간 동안 db 트랜잭션이 시작되어 느린 컬렉션을 DB에서 검색할 수 있습니다.
를 처리하는 가장 좋은 방법은JOIN FETCH
가져올 모든 엔티티에 대한 지시문을 지정합니다.
단, 몇 가지 답변에 따라 다음 안티패턴을 사용하지 마십시오.
때때로 엔티티를 가져오는 것보다 DTO 투영을 선택하는 것이 더 나을 수 있습니다.이 방법으로는 아무것도 얻을 수 없습니다.LazyInitializationException
.
persistence.xml에 다음 속성을 추가하면 일시적으로 문제가 해결될 수 있습니다.
<property name="hibernate.enable_lazy_load_no_trans" value="true" />
@vlad-mihalcea가 말한 바와 같이 느린 초기화 문제는 완전히 해결되지 않습니다.거래를 종료하기 전에 어소시에이션을 초기화하고 대신 DTO를 사용하십시오.
나도 유닛 테스트 할 때 이런 문제가 있었어.이 문제에 대한 매우 간단한 해결책은 @Transactional 주석을 사용하여 실행이 끝날 때까지 세션을 계속 여는 것입니다.
Custom Authentication Provider 클래스에는 다음 주석이 붙어야 합니다.
@트랜잭션
이것에 의해, 휴지 상태의 세션도 거기에 확실히 존재하게 됩니다.
그 이유는 느린 부하를 사용하면 세션이 닫히기 때문입니다.
두 가지 해결책이 있습니다.
게으른 짐을 쓰지 마세요.
★★
lazy=false
또는 XML로 설정합니다.@OneToMany(fetch = FetchType.EAGER)
주석으로.느린 부하를 사용하세요.
★★
lazy=true
또는 XML로 설정합니다.@OneToMany(fetch = FetchType.LAZY)
주석으로.OpenSessionInViewFilter filter
안에서web.xml
상세 내 게시물을 참조하십시오.
https://stackoverflow.com/a/27286187/1808417
에넘 컬렉션에 대해 이 문제를 겪고 있는 사용자를 위한 해결 방법은 다음과 같습니다.
@Enumerated(EnumType.STRING)
@Column(name = "OPTION")
@CollectionTable(name = "MY_ENTITY_MY_OPTION")
@ElementCollection(targetClass = MyOptionEnum.class, fetch = EAGER)
Collection<MyOptionEnum> options;
휴지 상태의 레이지 이니셜라이저를 사용할 수 있습니다.
이치
서 ★★★★PPIDO
입니다.
Hibernate.initialize(ppiDO);
if (ppiDO instanceof HibernateProxy) {
ppiDO = (PolicyProductInsuredDO) ((HibernateProxy) ppiDO).getHibernateLazyInitializer()
.getImplementation();
ppiDO.setParentGuidObj(policyDO.getBasePlan());
saveppiDO.add(ppiDO);
proxyFl = true;
}
우선 게으름과 거래에 대해 말한 모든 사용자들이 옳았다고 말하고 싶다.그러나 저의 경우 테스트에서 @Transactional 메서드를 사용한 결과와 실제 거래 이외의 결과가 약간 달라서 이 게으른 예외를 두게 되었습니다.
서비스 방법:
@Transactional
User get(String uid) {};
테스트 코드:
User user = userService.get("123");
user.getActors(); //org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role
이에 대한 저의 해결책은 이 코드를 다음과 같은 다른 트랜잭션으로 포장하는 것이었습니다.
List<Actor> actors = new ArrayList<>();
transactionTemplate.execute((status)
-> actors.addAll(userService.get("123").getActors()));
쓰는 은 '먹다'를 붙이는 '먹이다'를 .@Transactional
이치노
@Service
@Transactional
public class MyServiceImpl implements MyService{
...
}
@Transactional을 테스트 방법에 추가하는 통합 테스트 등 서비스 방법에 @Transactional 주석을 추가할 필요가 없는 경우가 있습니다.당신은 org.hibernate를 얻을 수 있습니다.Laze Initialization(레이지 초기화)트랜잭션일 필요가 없는 데이터베이스에서 선택한 메서드를 테스트할 때의 예외입니다.예를 들어 다음과 같이 느린 가져오기 관계를 가진 엔티티 클래스를 로드하려고 하면 다음과 같은 원인이 될 수 있습니다.
@OneToMany(mappedBy = "parent", fetch = FetchType.LAZY)
private List<Item> items;
따라서 @Transactional 주석을 테스트 방법에만 추가합니다.
@Test
@Transactional
public void verifySomethingTestSomething() {
페치를 에서 엔티티를 다시 합니다.LazyInitializationException
.
Hibernate.initialize(your entity);
JaVers를 사용하는 사용자의 경우 감사 대상 엔티티 클래스가 지정되면 이 클래스가 원인이 되는 속성을 무시할 수 있습니다.LazyInitializationException
" ("를 )@DiffIgnore
주석)을 클릭합니다.
이는 오브젝트 차이를 계산할 때 이러한 속성을 무시하도록 프레임워크에 지시하기 때문에 트랜잭션 범위 밖의 관련 오브젝트를 DB에서 읽으려고 하지 않습니다(따라서 예외가 발생합니다).
주석 추가
@JsonManagedReference
예를 들어 다음과 같습니다.
@ManyToMany(cascade=CascadeType.ALL)
@JoinTable(name = "autorizacoes_usuario", joinColumns = { @JoinColumn(name = "fk_usuario") }, inverseJoinColumns = { @JoinColumn(name = "fk_autorizacoes") })
@JsonManagedReference
public List<AutorizacoesUsuario> getAutorizacoes() {
return this.autorizacoes;
}
언급URL : https://stackoverflow.com/questions/22821695/how-to-fix-hibernate-lazyinitializationexception-failed-to-lazily-initialize-a
'programing' 카테고리의 다른 글
Vue TypeError _vm이 함수가 아닙니다. (0) | 2022.07.16 |
---|---|
Vue 상세 감시가 개체 속성 변경에 대해 작동하지 않음 (0) | 2022.07.10 |
오류: java: javacTask: 소스 릴리스 8에는 타깃 릴리스 1.8이 필요합니다. (0) | 2022.07.10 |
Vuejs에서 디스패치 처리 후 $emit에 문의 (0) | 2022.07.10 |
vuex API 요청에서 Vue 구성 요소의 데이터 초기화 (0) | 2022.07.10 |