Cara memperbaiki Hibernate LazyInitializationException: gagal menginisialisasi kumpulan peran dengan malas, tidak dapat menginisialisasi proxy - tidak ada Sesi

108

Di AuthenticationProvider kustom dari proyek musim semi saya, saya mencoba membaca daftar otoritas pengguna yang login, tetapi saya menghadapi kesalahan berikut:

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)

Membaca topik lain dari sini di StackOverflow, saya mengerti ini terjadi karena cara atribut jenis ini ditangani oleh kerangka kerja, tetapi saya tidak dapat menemukan solusi apa pun untuk kasus saya. Seseorang dapat menunjukkan kesalahan yang saya lakukan dan apa yang dapat saya lakukan untuk memperbaikinya?

Kode dari Custom AuthenticationProvider saya adalah:

@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);
    }

}

Kelas Entitas Saya adalah:

UsuarioHome.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;
    }
}

AutorizacoesUsuario.java

@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;
    }

}

Autorizacoes.java

@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;
    }
}

Proyek lengkap tersedia di github

-> https://github.com/klebermo/webapp_horario_livre

Kleber Mota
sumber
Ambil otoritas Anda dengan bersemangat atau gunakan OpenSessionInViewFilter.
Bart
itulah yang saya coba lihat bagaimana melakukannya. Apa yang saya coba adalah ini: Daftar <Autorizacoes> otoritas = user.getAutorizacoes () , di dalam fungsi yang sama dari alokasi UsernamePasswordAuthenticationToken, tetapi masih tidak berfungsi.
Kleber Mota
2
@ManyToMany(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
Bart
Oke, saya coba, tapi tetap tidak berhasil. Kelas Entitas Saya diperbarui: github.com/klebermo/webapp_horario_livre/blob/master/src/com/… , Penyedia Autentikasi saya saat ini: github.com/klebermo/webapp_horario_livre/blob/master/src/com/…
Kleber Mota

Jawaban:

140

Anda perlu menambahkan fetch=FetchType.EAGERdi dalam anotasi ManyToMany Anda untuk secara otomatis menarik kembali entitas anak:

@ManyToMany(fetch = FetchType.EAGER)

Opsi yang lebih baik adalah mengimplementasikan spring transactionManager dengan menambahkan berikut ini ke file konfigurasi spring Anda:

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

<tx:annotation-driven />

Anda kemudian dapat menambahkan anotasi @Transactional ke metode autentikasi Anda seperti:

@Transactional
public Authentication authenticate(Authentication authentication)

Ini kemudian akan memulai transaksi db selama durasi metode otentikasi yang memungkinkan setiap koleksi malas diambil dari db saat Anda mencoba menggunakannya.

jcmwright80.dll
sumber
1
Sebenarnya, saya memiliki transactionManager yang dikonfigurasi di aplikasi saya, dan saya menggunakannya di kelas DAO saya. Jika saya mencoba menggunakan metode otentikasi dari AuthenticationProvider seperti yang Anda sarankan, saya mendapatkan kesalahan Disebabkan oleh: java.lang.IllegalArgumentException: Tidak dapat mengatur bidang com.horariolivre.security.CustomAuthenticationProvider com.horariolivre.security.SecurityConfig.authenticationProvider ke $ Proxy36 . Saya mendapatkan kesalahan yang sama jika saya menggunakan add fetchType = FetchType.EAGER di dalam anotasi ManyToMany saya (dan saya dapat menggunakan ini hanya dalam satu atribut - Saya memiliki tiga jenis yang sama di kelas Entitas saya Usuario).
Kleber Mota
3
Anda perlu memandu entitas anak yang ingin Anda gunakan dalam Transaction untuk menghindari LazyInitializationException. Karena anotasi transaksional Anda berada pada level dao pada metode umum, Anda mungkin tidak ingin melakukannya di sana sehingga Anda perlu mengimplementasikan kelas layanan di depan dao yang memiliki batas @Transactional tempat Anda dapat menjalankan entitas anak yang diinginkan
jcmwright80
1
Protip untuk seseorang yang menghadapi ini untuk masa depan; @Transaction harus menggunakan metode publik. Jika tidak, ini tidak akan berhasil. Mungkin ada atau mungkin tidak ada peringatan.
Nicolas
menggunakan jenis fetch dan berfungsi dengan sempurna, tanyakan apa perbedaan menggunakan eager fetch ke bagian counter @transactional
Austine Gwa
1
@AustineGwa Perbedaan utama adalah menambahkan eager fetchType ke gabungan akan berarti daftar entitas anak akan selalu ditarik kembali dari DB setiap kali entitas utama dimuat sehingga ada potensi kinerja yang terpukul jika ada area fungsionalitas yang hanya memerlukan data dari entitas utama, jadi menggunakan transaksi dan pemuatan lambat memberi Anda lebih banyak kontrol atas jumlah data yang ditarik kembali, tetapi itu sepenuhnya bergantung pada aplikasi dan kasus penggunaan Anda terkait pendekatan mana yang tepat untuk Anda.
jcmwright80
36

Cara terbaik untuk menanganinyaLazyInitializationException adalah dengan menggunakan JOIN FETCHdirektif untuk semua entitas yang perlu Anda ambil.

Bagaimanapun, JANGAN gunakan Anti-Pola berikut seperti yang disarankan oleh beberapa jawaban:

Terkadang, proyeksi DTO adalah pilihan yang lebih baik daripada mengambil entitas, dan dengan cara ini, Anda tidak akan mendapatkannya LazyInitializationException.

Vlad Mihalcea
sumber
1
fetch join setara dengan eager fetching. Yang mungkin tidak selalu layak atau efisien. Juga cara biasa untuk mengambil objek bukanlah melalui kueri jpql. Fakta bahwa sesi terbuka adalah pandangan antipattern adalah jarak yang jauh, dan jujur, saya tidak setuju. Ini harus digunakan dengan hati-hati, tentu saja, tetapi ada banyak kasus penggunaan yang sangat bagus yang mendapat manfaat darinya.
fer.marino
4
Tidak, ini TIDAK . Sesi Terbuka dalam Tampilan diretas dan merupakan tanda bahwa entitas diambil bahkan untuk proyeksi hanya baca. Tidak ada banyak kasus penggunaan yang sangat bagus yang mendapatkan keuntungan darinya , tidak peduli seberapa keras Anda akan mencoba untuk membenarkannya. Tidak ada alasan untuk mengambil lebih banyak data daripada yang sebenarnya Anda butuhkan, serta tidak ada alasan untuk membocorkan pengambilan data di luar batas lapisan layanan transaksional.
Vlad Mihalcea
HI Vlad, Bisakah Anda jelaskan mengapa FETCH JOIN tidak setara dengan eager loading. Saya membaca artikel ini: blog.arnoldgalovics.com/2017/02/27/… . Dan dikatakan "Ide yang lebih baik adalah memuat relasi pada saat Anda memuat entitas induk - Perusahaan -. Ini dapat dilakukan dengan Ambil Gabung". Jadi ini adalah loading yang bersemangat. Bukan?
Geek
2
Pemimpin yang bersemangat berarti menambah FetchType.EAGERasosiasi Anda. JOIN FETCH adalah untuk FetchType.LAZYpengaitan yang perlu diambil dengan penuh semangat pada waktu kueri.
Vlad Mihalcea
25

Menambahkan properti berikut ke persistence.xml Anda dapat menyelesaikan masalah Anda untuk sementara

<property name="hibernate.enable_lazy_load_no_trans" value="true" />

Seperti yang dikatakan @ vlad-mihalcea itu antipattern dan tidak menyelesaikan masalah inisialisasi malas sepenuhnya, inisialisasi asosiasi Anda sebelum menutup transaksi dan sebagai gantinya gunakan DTO.

Mohammad-Hossein Jamali
sumber
16

Saya juga mengalami masalah ini saat melakukan Pengujian unit. Solusi yang sangat sederhana untuk masalah ini adalah dengan menggunakan anotasi @Transactional yang membuat sesi tetap terbuka hingga akhir eksekusi.

KarthikaSrinivasan
sumber
Apakah Anda menggunakan Hibernate Transational atau JPA Transactional?
jDub9
1
Saya menggunakan Hibernate
KarthikaSrinivasan
11

Alasannya adalah saat Anda menggunakan lazy load, sesi ditutup.

Ada dua solusi.

  1. Jangan gunakan lazy load.

    Atur lazy=falsedalam XML atau Atur @OneToMany(fetch = FetchType.EAGER)dalam anotasi.

  2. Gunakan lazy load.

    Atur lazy=truedalam XML atau Atur @OneToMany(fetch = FetchType.LAZY)dalam anotasi.

    dan tambahkan OpenSessionInViewFilter filter Andaweb.xml

Detail Lihat posting saya.

https://stackoverflow.com/a/27286187/1808417

saneryee
sumber
1
OpenSessionInViewFilter juga merupakan anti-pola. Saya juga menyarankan untuk tidak pernah menetapkan pemetaan ke EAGER karena akan ada banyak kasus di mana Anda tidak memerlukan data tersebut dalam koleksi EAGER dan Anda akan menarik lebih banyak data daripada yang dibutuhkan kasus penggunaan tersebut dan sangat mengurangi kinerja Anda. Harap simpan semua pemetaan MALAS dan tambahkan join fetch ke Kueri Anda.
pengguna1567291
7

Kelas Custom AuthenticationProvider Anda harus dianotasi dengan berikut ini:

@Transaksi

Ini akan memastikan kehadiran sesi hibernasi di sana juga.

Bilal Ahmed Yaseen
sumber
6

Anda dapat menggunakan penginisialisasi malas hibernate.

Di bawah ini adalah kode yang bisa Anda referensikan.
Berikut PPIDOadalah objek data yang ingin saya ambil

Hibernate.initialize(ppiDO);
if (ppiDO instanceof HibernateProxy) {
    ppiDO = (PolicyProductInsuredDO) ((HibernateProxy) ppiDO).getHibernateLazyInitializer()
        .getImplementation();
    ppiDO.setParentGuidObj(policyDO.getBasePlan());
    saveppiDO.add(ppiDO);
    proxyFl = true;
}
Mitesh C
sumber
4

Bagi mereka yang memiliki masalah dengan kumpulan enum berikut adalah cara mengatasinya:

@Enumerated(EnumType.STRING)
@Column(name = "OPTION")
@CollectionTable(name = "MY_ENTITY_MY_OPTION")
@ElementCollection(targetClass = MyOptionEnum.class, fetch = EAGER)
Collection<MyOptionEnum> options;
Sasha Shpota
sumber
Ini berhasil untuk saya. Saya juga menguji opsi untuk menambahkan @Transactional dan itu juga berfungsi. Tapi saya memilih opsi ini.
rick dana
2

Pertama-tama saya ingin mengatakan bahwa semua pengguna yang mengatakan tentang malas dan transaksi itu benar. Tetapi dalam kasus saya, ada sedikit perbedaan di mana saya menggunakan hasil metode @Transactional dalam pengujian dan itu di luar transaksi nyata jadi saya mendapat pengecualian malas ini.

Metode layanan saya:

@Transactional
User get(String uid) {};

Kode tes saya:

User user = userService.get("123");
user.getActors(); //org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role

Solusi saya untuk ini adalah membungkus kode itu dalam transaksi lain seperti ini:

List<Actor> actors = new ArrayList<>();
transactionTemplate.execute((status) 
 -> actors.addAll(userService.get("123").getActors()));
vk23
sumber
1

Saya yakin daripada mengaktifkan eager fetch, masuk akal untuk menginisialisasi ulang entitas Anda di tempat yang diperlukan untuk menghindari LazyInitializationExceptionpengecualian

Hibernate.initialize(your entity);
Pravin
sumber
0

Untuk mereka yang menggunakan JaVers , diberikan kelas entitas yang diaudit, Anda mungkin ingin mengabaikan properti yang menyebabkan LazyInitializationExceptionpengecualian (misalnya dengan menggunakan @DiffIgnoreanotasi).

Ini memberitahu kerangka kerja untuk mengabaikan properti tersebut saat menghitung perbedaan objek, sehingga kerangka tidak akan mencoba untuk membaca dari DB objek terkait di luar cakupan transaksi (sehingga menyebabkan pengecualian).

nickshoe
sumber
0

Praktik umum adalah menempatkan di @Transactionalatas kelas layanan Anda.

@Service
@Transactional
public class MyServiceImpl implements MyService{
...
}
Deb
sumber
-1

Tambahkan anotasi

@JsonManagedReference

Sebagai contoh:

@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;
}
Mauricio
sumber