Java Hibernate删除对象

Java Hibernate删除对象,java,hibernate,Java,Hibernate,今天我用hibernate做了一些实验。 首先,我的计划背后没有更深层次的意义。我只是想试试这个框架。 我计划了以下db表: 汽车(汽车) 司机(法赫勒) 沃农(公寓) 客人(法尔加斯特) 使用以下双向映射: 驱动装置-扁平单孔 司机-汽车公司 汽车-客人众多 在准备好单个类之后,我编写了我的worker来插入一些解调数据。到目前为止,一切正常。 最后,我想删除我的一个驱动程序。但是hibernate告诉我,它会被某个客人重新保存。不幸的是,我不明白为什么。 我希望在将驾驶员从相应车辆的

今天我用hibernate做了一些实验。 首先,我的计划背后没有更深层次的意义。我只是想试试这个框架。 我计划了以下db表:

  • 汽车(汽车)
  • 司机(法赫勒)
  • 沃农(公寓)
  • 客人(法尔加斯特)
使用以下双向映射:

  • 驱动装置-扁平单孔
  • 司机-汽车公司
  • 汽车-客人众多
在准备好单个类之后,我编写了我的worker来插入一些解调数据。到目前为止,一切正常。 最后,我想删除我的一个驱动程序。但是hibernate告诉我,它会被某个客人重新保存。不幸的是,我不明白为什么。 我希望在将驾驶员从相应车辆的驾驶员集合中移除后,一切都会好起来

班车

package mycode;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name="auto")
public class Auto {

@Id @GeneratedValue
private int id;
@Column(name="nummernschild", nullable = false)
private String nummernschild;
@OneToMany(cascade=CascadeType.ALL, mappedBy="auto")
private List<Fahrer>fahrers = new ArrayList<Fahrer>();
@ManyToMany(cascade=CascadeType.ALL)
private List<Fahrgast>fahrgasts = new ArrayList<Fahrgast>();

public List<Fahrgast> getFahrgasts() {
    return fahrgasts;
}
public void setFahrgasts(List<Fahrgast> fahrgasts) {
    this.fahrgasts = fahrgasts;
}
public List<Fahrer> getFahrers() {
    return fahrers;
}
public void setFahrers(List<Fahrer> fahrers) {
    this.fahrers = fahrers;
}
private LocalDate kaufdatum;
public LocalDate getKaufdatum() {
    return kaufdatum;
}
public void setKaufdatum(LocalDate kaufdatum) {
    this.kaufdatum = kaufdatum;
}
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getNummernschild() {
    return nummernschild;
}
public void setNummernschild(String nummernschild) {
    this.nummernschild = nummernschild;
}

}
班级公寓

package mycode;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToOne;
import javax.persistence.Table;

import org.hibernate.annotations.GenericGenerator;
import org.hibernate.annotations.Parameter;

@Entity
@Table(name="wohnung")
public class Wohnung {
    @Id @GeneratedValue(generator = "newGenerator")
    @GenericGenerator(name="newGenerator", strategy="foreign" , parameters= {@Parameter(value="fahrer", name="property")})
private int id; 
@Column(nullable=false)
private String ort, straße;
@OneToOne(cascade=CascadeType.ALL)
@JoinColumn(name="id")
private Fahrer fahrer;
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public String getOrt() {
    return ort;
}
public void setOrt(String ort) {
    this.ort = ort;
}
public String getStraße() {
    return straße;
}
public void setStraße(String straße) {
    this.straße = straße;
}
public Fahrer getFahrer() {
    return fahrer;
}
public void setFahrer(Fahrer fahrer) {
    this.fahrer = fahrer;
}


}
班客

package mycode;

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

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

@Entity
@Table(name="fahrgast")
public class Fahrgast {
@Id @GeneratedValue
private int id;
@Column(nullable=false)
private int kundennummmer;
private String vornname, nachname;
@ManyToMany(mappedBy="fahrgasts")
private List<Auto>autos = new ArrayList<Auto>();

public List<Auto> getAutos() {
    return autos;
}
public void setAutos(List<Auto> autos) {
    this.autos = autos;
}
public int getId() {
    return id;
}
public void setId(int id) {
    this.id = id;
}
public int getKundennummmer() {
    return kundennummmer;
}
public void setKundennummmer(int kundennummmer) {
    this.kundennummmer = kundennummmer;
}
public String getVornname() {
    return vornname;
}
public void setVornname(String vornname) {
    this.vornname = vornname;
}
public String getNachname() {
    return nachname;
}
public void setNachname(String nachname) {
    this.nachname = nachname;
}


}
封装mycode;
导入java.util.ArrayList;
导入java.util.List;
导入javax.persistence.Column;
导入javax.persistence.Entity;
导入javax.persistence.GeneratedValue;
导入javax.persistence.Id;
导入javax.persistence.ManyToMany;
导入javax.persistence.Table;
@实体
@表(name=“fahrgast”)
公共类法尔加斯特{
@Id@GeneratedValue
私有int-id;
@列(nullable=false)
昆登纳姆私人酒店;
私有字符串vornname、nachname;
@许多(mappedBy=“fahrgasts”)
private Listautos=new ArrayList();
公共列表getAutos(){
返回汽车;
}
公共作废自动设置(列出自动设置){
this.autos=autos;
}
公共int getId(){
返回id;
}
公共无效集合id(内部id){
this.id=id;
}
public int getkundennummer(){
返回Kundennummer;
}
公共无效设置KundenNummer(int KundenNummer){
this.kundennummer=kundennummer;
}
公共字符串getVornname(){
返回沃纳姆;
}
公共void setVornname(字符串vornname){
this.vornname=vornname;
}
公共字符串getNachname(){
返回nachname;
}
公共无效设置nachname(字符串nachname){
this.nachname=nachname;
}
}
班主任

package mycode;

import java.time.LocalDate;
import java.util.ArrayList;
import java.util.List;

import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.cfg.Configuration;

public class Worker {

    private Session session;
    private SessionFactory sf;
    public static void main(String[] args) {

        Worker worker = new Worker();
        worker.work();
    }

    private void init()
    {
        Configuration configuration = new Configuration().configure();

        sf = configuration.buildSessionFactory();
        session = sf.openSession();

    }

    private void work()
    {
        init();
        Auto auto = new Auto(); 
        auto.setNummernschild("HH:MK:"+1);
        LocalDate ld = LocalDate.now();
        auto.setKaufdatum(ld);

        session.beginTransaction();
        for (int i=0; i<10; i++)
        {


            auto = new Auto();
            auto.setNummernschild("HH:MK:"+i);
            ld = LocalDate.now();
            auto.setKaufdatum(ld);

            Auto auto2 = new Auto();

            auto2.setNummernschild("HH:MK:"+i);
            ld = LocalDate.now();
            auto2.setKaufdatum(ld);

            //auto.setId(i);

            Fahrer fahrer = new Fahrer(); 
            fahrer.setVorname("Hans");
            fahrer.setNachname("Huber");
            Fahrer fahrer2 = new Fahrer(); 
            fahrer2.setVorname("Anna");
            fahrer2.setNachname("Schmidt");
            double temp = Math.random();
            int alter = (int)(temp*50);
            fahrer.setAlter(alter);

            fahrer2.setAlter(alter);

            fahrer.setAuto(auto);
            fahrer2.setAuto(auto2);
            Wohnung wohnung = createWohnung(i);
            wohnung.setFahrer(fahrer);
            fahrer.setWohnung(wohnung);
            Wohnung wohnung2 = createWohnung(i*10);
            fahrer2.setWohnung(wohnung2);
            wohnung2.setFahrer(fahrer2);
            auto.getFahrers().add(fahrer);
            auto2.getFahrers().add(fahrer2);

            double zufall = Math.random()*100;
            int zu = (int)zufall;
            for (int z=0; z<zu; z++)
            {
                Fahrgast fahrgast = new Fahrgast(); 
                fahrgast.setVornname("Hans"+z);
                fahrgast.setNachname("Dampf"+z);
                double kundennummer = Math.random()*10000;
                fahrgast.setKundennummmer((int)kundennummer);
                fahrgast.getAutos().add(auto);
                fahrgast.getAutos().add(auto2);
                auto.getFahrgasts().add(fahrgast);
                auto2.getFahrgasts().add(fahrgast);

            }
//          session.save(fahrer);
//          session.save(fahrer2);
            session.save(auto);
            session.save(auto2);

        }

        Fahrer abfrage = session.get(Fahrer.class, 2);
        List<Fahrer>fahrers = session.createCriteria(Fahrer.class).list();
        List<Fahrer>tobedeletet = new ArrayList<Fahrer>();
        for (Fahrer aktuell : fahrers)
        {
            Auto car = aktuell.getAuto();
            List<Fahrer>cardriver = car.getFahrers();
            Fahrer temp = null;
            for (Fahrer driver: cardriver)
            {
                if (driver.getId()==abfrage.getId())
                {
                    tobedeletet.add(aktuell);
                    temp = driver;

                }
            }
            cardriver.remove(temp);
            session.update(car);
        }


        for (Fahrer aktuell : tobedeletet)
        {
            session.remove(aktuell);
        }


        System.out.println(abfrage.getVorname()+ " "+abfrage.getNachname());


        session.getTransaction().commit();
        session.close();
        sf.close();

    }

    private Wohnung createWohnung(int i)
    {
        Wohnung wohnung = new Wohnung(); 
        wohnung.setOrt("bla"+i);
        wohnung.setStraße("blub"+i);
        return wohnung;
    }

}
封装mycode;
导入java.time.LocalDate;
导入java.util.ArrayList;
导入java.util.List;
导入org.hibernate.Session;
导入org.hibernate.SessionFactory;
导入org.hibernate.boot.registry.StandardServiceRegistryBuilder;
导入org.hibernate.cfg.Configuration;
公社工人{
非公开会议;
私人会话工厂sf;
公共静态void main(字符串[]args){
工人=新工人();
工人。工作();
}
私有void init()
{
配置=新配置().configure();
sf=configuration.buildSessionFactory();
session=sf.openSession();
}
私人工作()
{
init();
自动=新自动();
auto.setNummernschild(“HH:MK:+1”);
LocalDate ld=LocalDate.now();
自动设置数据(ld);
session.beginTransaction();
对于(int i=0;i

您的异常显示:从关联中删除删除的对象

只要从
Auto#fahrers
集合中删除fahrer并自动更新就足够了:

auto.getFahrers().remove(fahrer);
// remove other fahrers
session.update(auto);
因为您在auto类中的auto-to-fahrers关系上有一个
cascade=CascadeType.ALL
属性,所以更新auto后,应该自动删除Fahrer

更多关于这里:

还有几件事需要注意:

  • 请在代码中使用一种语言:)。
    Auto car=aktuell.getAuto();
    。您可以使用Auto,但变量名为car

  • PostgreSqlDialogue已弃用,请在hibernate配置中选择PostgreSql9Dialogue或其他

  • auto
    是保留名称,最好使用其他名称

多亏了Oles, 我将代码更新为

List<Auto>autos = session.createCriteria(Auto.class).list();
        List<Auto>toBeUpdated = new ArrayList<Auto>();
        for (Auto fahzeug : autos)
        {
            List<Fahrer>fahrers2 = fahzeug.getFahrers();
            for (Fahrer aktuell : fahrers2)
            {
                if (aktuell.getId()==abfrage.getId())
                {
                    toBeUpdated.add(fahzeug);
                }
            }

        }
        for (Auto fahrzeug : toBeUpdated)
        {
            fahrzeug.getFahrers().remove(abfrage);
            System.out.println("removed");
            session.update(fahrzeug);
        }
Listautos=session.createCriteria(Auto.class.list();
ListtoBeUpdated=新建ArrayList();
用于(自动fahzeug:autos)
{
Listfahrers2=fahzeug.getFahrers();
对于(Fahrer-aktuell:fahrers2)
{
if(aktuell.getId()==abfrage.getId())
{
toBeUpdated.add(fahzeug);
}
}
}
用于(自动华氏度:toBeUpdated)
{
fahrzeug.getFahrers().remove(abfrage);
系统输出打印项次(“删除”);
更新会议(fahrzeug);
}

不幸的是,有些东西仍然无法按预期工作。我无法在fahrerloop内执行删除操作,因为这会以concurrentmodificationexception结束。根据此处发布的代码,没有其他异常。调试视图向我显示,在最后一个循环后,其中一辆车没有司机。尤其是司机从驱动程序列表中删除id为2的。不幸的是,驱动程序仍保留在数据库中。如果我正确理解了最后一个答案,情况就不应该如此。

首先,希望您知道
alter
是一个保留字,
alter table;
,因此您必须更改Fahrer类中的列名:

@Column(name = "_alter") // choose any name you want
private int alter;
在那之后,你为什么需要这么多双向关系?看,你有:

class Fahrer {
    // ...
    @ManyToOne(cascade = CascadeType.ALL)
    private Auto auto;
这意味着,当你删除一个fahrer时,自动删除为。这真的是你想要的吗

现在看看您的代码:

// at first you check if the ID is equal to abfrage and add it to list
if (driver.getId() == abfrage.getId()) {
    tobedeletet.add(aktuell);
    temp = driver;
}

// at the end you formed a list tobedeleted witch contains elements with the same ID.

for (Fahrer aktuell : tobedeletet) {
    session.remove(aktuell);
}

老实说,我是java初学者,所以我可能会错过一些东西。但是删除具有相同ID值的实体几次可能是不必要的。

您可以发布错误消息吗?添加了解决问题的错误消息。fahrer和auto之间的级联类型是问题所在。
class Fahrer {
    // ...
    @ManyToOne(cascade = CascadeType.ALL)
    private Auto auto;
// at first you check if the ID is equal to abfrage and add it to list
if (driver.getId() == abfrage.getId()) {
    tobedeletet.add(aktuell);
    temp = driver;
}

// at the end you formed a list tobedeleted witch contains elements with the same ID.

for (Fahrer aktuell : tobedeletet) {
    session.remove(aktuell);
}