Java hibernate fetchtype eager运行良好,而fetchtype lazy最终会出现异常

时间:2017-11-18 18:45:11

标签: java hibernate

今天我用hibernate做了一些进一步的实验。 我的数据库中有书籍,用户和租赁。 每本书都知道匹配的租金,每个人 tal知道匹配的书和匹配的用户,最后每个用户都知道匹配的租金。

在向我想要检查的用户提供书籍之前,如果之前已经回复过。 因此,我想浏览与书籍相关的租金清单,如果有没有返回日期的租金,我知道出了问题。

一切正常,只要我在我的书类中使用fetchtype.EAGER。 当然我更喜欢LAZY,因为我在书上还有一些其他操作,不需要知道连接的租金。 但如果我改为懒惰,我会得到以下异常:

Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException
    at org.hibernate.collection.internal.AbstractPersistentCollection.openTemporarySessionForLoading(AbstractPersistentCollection.java:275)
    at org.hibernate.collection.internal.AbstractPersistentCollection.withTemporarySessionIfNeeded(AbstractPersistentCollection.java:198)
    at org.hibernate.collection.internal.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:561)
    at org.hibernate.collection.internal.AbstractPersistentCollection.read(AbstractPersistentCollection.java:132)
    at org.hibernate.collection.internal.PersistentBag.iterator(PersistentBag.java:277)
    at code.worker.Verleihworker.verleihen(Verleihworker.java:153)
    at code.worker.Verleihworker.access$5(Verleihworker.java:145)
    at code.worker.Verleihworker$3.actionPerformed(Verleihworker.java:135)
    at javax.swing.AbstractButton.fireActionPerformed(AbstractButton.java:2022)

我真的不明白为什么会这样。我认为懒惰意味着,租金会尽快加载,因为我需要它们。

package code.logik;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.annotations.ManyToAny;

@Entity
@Table(name="buch")
public class Buch {

    @Column(nullable=false)
    private String titel;
    private String autor;

    @ManyToOne
    private WlBuchart wlBuchart;

    @OneToMany(cascade=CascadeType.ALL, mappedBy="buch", fetch=FetchType.LAZY)
    private List<Leihstellung>leihstellungs;

    public WlBuchart getWlBuchart() {
        return wlBuchart;
    }

    public void setWlBuchart(WlBuchart wlBuchart) {
        this.wlBuchart = wlBuchart;
    }

    @Id
    private int nummer;



    public Buch(String titel, String autor,int nummer) {
        this.titel=titel; 
        this.autor=autor; 
        this.nummer=nummer;
        leihstellungs = new ArrayList<>();
    }

    public Buch() {
        // TODO Auto-generated constructor stub
    }


    public String getTitel() {
        return titel;
    }

    public String getAutor() {
        return autor;
    }



    public int getNummer() {
        return nummer;
    }

    public List<Leihstellung> getLeihstellungs() {
        return leihstellungs;
    }

    public void addLeihstellung(Leihstellung leihstellung)
    {
        leihstellungs.add(leihstellung);
    }

    public void removeLeihstellung(Leihstellung leihstellung)
    {
        leihstellungs.remove(leihstellung);
    }

    public void setTitel(String titel) {
        this.titel = titel;
    }

    public void setAutor(String autor) {
        this.autor = autor;
    }


}


package code.logik;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

import org.hibernate.Session;

@Entity
@Table(name="benutzer")
public class Benutzer {

    @Column(nullable=false)
    private String vorname, nachname, gruppe; 
    @Id
    private String kennung;
    private boolean admin;
    @Column(nullable=true)
    private String kennwort;

    @OneToMany(cascade=CascadeType.ALL, orphanRemoval =true, mappedBy="benutzer", fetch=FetchType.EAGER)
    private List<Leihstellung>leihstellungs;


    public String getKennwort() {
        return kennwort;
    }

    public void setKennwort(String kennwort) {
        this.kennwort = kennwort;
    }

    public Benutzer(String vorname, String nachname, String gruppe, String kennung) {
        this.vorname=vorname; 
        this.nachname=nachname; 
        this.gruppe=gruppe; 
        this.kennung=kennung;
        this.leihstellungs= new ArrayList<>();

    }

    public Benutzer() {
        // TODO Auto-generated constructor stub
    }

    public String getVorname() {
        return vorname;
    }

    public String getNachname() {
        return nachname;
    }

    public String getGruppe() {
        return gruppe;
    }

    public String getKennung() {
        return kennung;
    }

    public boolean isAdmin() {
        return admin;
    }

    public void setAdmin(boolean admin) {
        this.admin = admin;
    }

    public List<Leihstellung> getLeihstellungs() {
        return leihstellungs;
    }

    public void addLeihstellung(Leihstellung leihstellung)
    {
        leihstellungs.add(leihstellung);
    }



    public int compare(Benutzer other)
    {
        if (this.getNachname().compareTo(other.getNachname())!=0)
        {
            return this.getNachname().compareTo(other.getNachname());
        }
        return this.getVorname().compareTo(other.getVorname());
    }

    public void removeLeihstellungen(Session session)
    {
        for (Leihstellung current : leihstellungs)
        {
            current.removeFromBuch(session);
        }
        leihstellungs = null;
        session.update(this);
    }


}

package code.logik;

import java.time.LocalDate;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

import org.hibernate.Session;

@Entity
@Table(name="leihstellung")
public class Leihstellung {

    @ManyToOne
    private Benutzer benutzer; 

    @Id @GeneratedValue
    private int id;

    @Column(nullable=false)
    private LocalDate von;

    private LocalDate bis;

    @ManyToOne
    private Buch buch;

    public Leihstellung(Benutzer benutzer, Buch buch) {
        this.benutzer=benutzer; 
        this.buch=buch; 
        this.von = LocalDate.now();
    }

    public Leihstellung() {
        // TODO Auto-generated constructor stub
    }

    public void setAbgegeben()
    {
        bis = LocalDate.now();
    }

    public Benutzer getBenutzer() {
        return benutzer;
    }

    public int getId() {
        return id;
    }

    public LocalDate getVon() {
        return von;
    }

    public LocalDate getBis() {
        return bis;
    }

    public Buch getBuch() {
        return buch;
    }

    public void updateBenutzer()
    {
        benutzer = null;
    }

    public void removeFromBuch(Session session)
    {
        buch.removeLeihstellung(this);
        session.update(buch);
    }


}


package code.worker;

import java.awt.Desktop.Action;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.awt.event.MouseEvent;
import java.awt.event.MouseListener;
import java.util.List;

import org.hibernate.Session;

import Tools.Sessiongetter;
import code.logik.Benutzer;
import code.logik.Buch;
import code.logik.Leihstellung;
import code.logik.Worker;
import gui.Ausleihe;
import gui.RentError;

public class Verleihworker {

    private Ausleihe ausleihe; 
    private Buch buch;
    private Benutzer benutzer;
    private Worker worker;

    public Verleihworker(Ausleihe ausleihe, Worker worker) {
        this.ausleihe=ausleihe;
        this.worker=worker;
    }

    public void work()
    {
        MouseListener buchlistener = new MouseListener() {

            @Override
            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseExited(MouseEvent e) {
                Buchgetter buchgetter = new Buchgetter(); 
                Buch temp = null;
                try
                {
                    temp = buchgetter.getBuch(Integer.parseInt(ausleihe.getBuchText()));
                }
                catch (Exception ex)
                {

                }
                if (temp !=null)
                {
                    buch = temp;
                    ausleihe.setBuchText(buch.getTitel());
                }


            }

            @Override
            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseClicked(MouseEvent e) {
                // TODO Auto-generated method stub

            }
        };

        MouseListener benutzerlistener = new MouseListener() {

            @Override
            public void mouseReleased(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mousePressed(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseExited(MouseEvent e) {
                Benutzergetter benutzergetter = new Benutzergetter(); 
                Benutzer temp = null;
                try
                {
                     temp = benutzer = benutzergetter.getBenutzer(ausleihe.getBenutzerText());
                }
                catch (Exception ex)
                {

                }
                if (temp!=null)
                {
                    benutzer=temp;
                    ausleihe.setBenutzerText(benutzer.getVorname()+" "+benutzer.getNachname());
                }


            }

            @Override
            public void mouseEntered(MouseEvent e) {
                // TODO Auto-generated method stub

            }

            @Override
            public void mouseClicked(MouseEvent e) {
                // TODO Auto-generated method stub

            }
        };
        ActionListener al = new ActionListener() {

            @Override
            public void actionPerformed(ActionEvent e) {
                if (buch!=null && benutzer !=null)
                {
                    verleihen();
                }

            }
        };
        ausleihe.addSchuelerListener(benutzerlistener);
        ausleihe.addBuchListener(buchlistener);
        ausleihe.addButtonListener(al);
    }

    private void verleihen()
    {
        Sessiongetter sg = new Sessiongetter(); 
        Session session = sg.getSesseion();
        session.beginTransaction();

        List<Leihstellung>buchLeihstellungen = buch.getLeihstellungs();
        boolean problem = false;
        for (Leihstellung aktuell : buchLeihstellungen)
        {
            if (aktuell.getBis()==null)
            {
                Benutzer hatNoch = aktuell.getBenutzer();
                problem=true;
                System.out.println("Das Buch mit dem Titel "+buch.getTitel()+" ist noch an "+hatNoch.getVorname()+" "+hatNoch.getNachname()+" verliehen");
                RentError rentError = new RentError(); 
                rentError.setText(" Das Bucht "+buch.getTitel()+" ist laut Datenbank noch an "+hatNoch.getVorname()+" "+hatNoch.getNachname()+" verliehen. Bitte verbuchen Sie erst die Rückgabe");
                worker.addView(rentError, "renterror");
                worker.showPanel("renterror");

                ActionListener al = new ActionListener() {

                    @Override
                    public void actionPerformed(ActionEvent e) {
                        worker.showPanel("mm");
                        worker.removeCard("renterror");
                    }
                };
                rentError.addActionListener(al);
            }
        }
        if (!problem)
        {
            Leihstellung leihstellung = new Leihstellung(benutzer, buch);
            buch.addLeihstellung(leihstellung);
            benutzer.addLeihstellung(leihstellung);
            session.save(leihstellung);
            session.update(benutzer);
            session.update(buch);
            session.getTransaction().commit();
            session.close();
            sg.closeSessionFactory();

        }


    }



}

package Tools;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.Configuration;

public class Sessiongetter {

    private SessionFactory sf; 

    private void init()
    {
        if (sf==null)
        {
            Configuration configuration = new Configuration().configure();
            sf = configuration.buildSessionFactory();
        }
    }

    public Session getSesseion()
    {
        init();
        return sf.openSession();
    }

    public void closeSessionFactory()
    {
        sf.close();
    }

}

<?xml version='1.0' encoding='utf-8'?>

<!--
  ~ Hibernate, Relational Persistence for Idiomatic Java
  ~
  ~ License: GNU Lesser General Public License (LGPL), version 2.1 or later.
  ~ See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
  -->
<!DOCTYPE hibernate-configuration SYSTEM
        "http://www.hibernate.org/dtd/hibernate-configuration-3.0.dtd">
<hibernate-configuration
>
    <session-factory>
        <!-- Database connection settings -->
        <property name="connection.driver_class">org.postgresql.Driver</property>
        <property name="connection.url">jdbc:postgresql://192.168.2.252:5432/schulbib</property>
        <property name="connection.username">postgres</property>
        <property name="connection.password">postgres</property>

        <property name="hibernate.temp.use_jdbc_metadata_defaults">false</property>
        <property name="hibernate.enable_lazy_load_no_trans">true</property>

        <!-- JDBC connection pool (use the built-in) -->
        <property name="connection.pool_size">1</property>

        <!-- SQL dialect -->
        <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property>

        <!-- Enable Hibernate's automatic session context management -->
        <property name="current_session_context_class">thread</property>

        <!-- Disable the second-level cache  -->
        <property name="cache.provider_class">org.hibernate.cache.internal.NoCacheProvider</property>

        <!-- Echo all executed SQL to stdout -->
        <property name="show_sql">true</property>

        <!-- Drop and re-create the database schema on startup -->

        <mapping class="code.logik.Buch"/>
        <mapping class="code.logik.WlBuchart"/>
        <mapping class="code.logik.Benutzer"/>
        <mapping class="code.logik.Leihstellung"/>
    </session-factory>
</hibernate-configuration>

0 个答案:

没有答案