今天我用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>