2017-08-20 7 views
0

今日、私は休止状態でいくつかの実験を行いました。 まず第一に、私のプログラムの背後には深い意味がありません。私はフレームワークを試したがりました。以下の双方向マッピングとJava Hibernate delete Object

  • 車(自動車)
  • ドライバー(Fahrer)
  • Wohnung(フラット)
  • ユーザーレビュー(Fahrgast)

: は、私は、次のDBのテーブルをかんな:

  • ドライバ - フラットオンエトン
  • ドライバ - 車
  • 車onetomany - ゲスト多対多

単一のクラスを準備した後、私はいくつかのDEMODATAを挿入するために、私の労働者を書きました。これまではすべてが期待通りに機能します。 最後に私のドライバを削除したいと思います。しかし、休止状態は、特定のゲストによって再保存されることを私に伝えます。残念ながら私は理由を理解できません。 対応する車のドライバコレクションからドライバを削除した後、すべてがうまくいくことを期待しました。

クラスの車

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.Entity; 
import javax.persistence.GeneratedValue; 
import javax.persistence.Id; 
import javax.persistence.JoinColumn; 
import javax.persistence.ManyToOne; 
import javax.persistence.OneToOne; 
import javax.persistence.Table; 

@Entity 
@Table(name="fahrer") 
public class Fahrer { 
@Id @GeneratedValue() 
private int id; 
private String vorname, nachname; 
private int alter; 

@OneToOne (cascade=CascadeType.ALL) 
@JoinColumn(name="id") 
private Wohnung wohnung; 
@ManyToOne(cascade=CascadeType.ALL) 
private Auto auto; 


public Auto getAuto() { 
    return auto; 
} 
public void setAuto(Auto auto) { 
    this.auto = auto; 
} 
public Wohnung getWohnung() { 
    return wohnung; 
} 
public void setWohnung(Wohnung wohnung) { 
    this.wohnung = wohnung; 
} 

public int getId() { 
    return id; 
} 
public void setId(int id) { 
    this.id = id; 
} 
public String getVorname() { 
    return vorname; 
} 
public void setVorname(String vorname) { 
    this.vorname = vorname; 
} 
public String getNachname() { 
    return nachname; 
} 
public void setNachname(String nachname) { 
    this.nachname = nachname; 
} 
public int getAlter() { 
    return alter; 
} 
public void setAlter(int alter) { 
    this.alter = alter; 
} 

} 

クラスフラット

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


} 

クラスワーカー

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

} 

最後にコンフィギュレーションファイル

<?xml version='1.0' encoding='utf-8'?> 
<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/test</property> 
    <property name="connection.username">postgres</property> 
    <property name="connection.password">postgres</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 --> 
    <property name="hbm2ddl.auto">create</property> 
    <mapping class="mycode.Auto"/> 
    <mapping class="mycode.Fahrer"/> 
    <mapping class="mycode.Wohnung"/> 
    <mapping class="mycode.Fahrgast"/> 
</session-factory> 

は、誰もが私のドライバーの1を削除する方法を、教えてもらえますか?

エラーメッセージ: ERROR:HHH000346:管理フラッシュ中にエラーが発生しました[削除されたオブジェクトがカスケードによって再保存されます(団体から削除されたオブジェクトを削除する):[mycode.Fahrgast#3]]のスレッドで 例外「メイン」削除されたオブジェクトを関連から削除する:[mycode.Fahrgast#3] at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:126) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:155) at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:162) at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java :1441) at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:491) at org.hibernate.internal.SessionImpl。org.hibernate.engine.jdbc.internal.JdbcCoordinatorImpl.beforeTransactionCompletion(JdbcCoordinatorImpl.java:467) でorg.hibernate.internal.SessionImpl.beforeTransactionCompletion(SessionImpl.java:2411) でflushBeforeTransactionCompletion(SessionImpl.java:3201) でorg.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.access $ 100℃でorg.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl.beforeCompletionCallback(JdbcResourceLocalTransactionCoordinatorImpl.java:146) (JdbcResourceLocalTransactionCoordinatorImpl.java:38 ) at org.hibernate.resource.transaction.backend.jdbc.internal.JdbcResourceLocalTransactionCoordinatorImpl $ TransactionDriverControlImpl.commit(JdbcResourceLocalTransactionCoordinatorImpl.java:220)(Worker.java:19) で、

+0

エラーメッセージを投稿できますか? –

+0

がエラーメッセージ –

答えて

1

まず第一に、物事は、あなたがalterが予約語、alter table <table_name>;ですので、あなたがFahrerクラスで自分の列名を変更する必要があることを知っ願っています:その後

@Column(name = "_alter") // choose any name you want 
private int alter; 

、なぜこれほど多くの双方向の関係が必要なのか?そして、あなたは持っています:

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

は、正直に言うと、私はJavaの初心者ですので、私は何かを逃すことがあります。しかし、同じID値を持つエンティティを数回削除することは、必然的に必要ではありません。

+0

を追加しました。これで問題は解決しました。ファーラーとオートの間のカスケードタイプが問題でした。 –

0

あなたの例外は言う:団体

から削除削除されたオブジェクトは、ちょうどAuto#fahrersコレクションからfahrerを削除して自動更新するのに十分でsould:

auto.getFahrers().remove(fahrer); 
// remove other fahrers 
session.update(auto); 

あなたがcascade=CascadeType.ALL性質を持っているのできみのオートクラスのオートファーラーの関係は、自動更新後、ファーラーは自動的に削除する必要があります。

ここについての詳細:注目すべきhttps://stackoverflow.com/a/11649941/6521788

そして、いくつかのこと:

  • PLEASE、あなたのコード内で一つの言語を使用します:)。 Auto car = aktuell.getAuto();。あなたはautoを取得しますが、変数はcarと呼ばれます。

  • PostgreSQLDialectは非推奨です。休止状態の設定でPostgreSQL9Dialectなどを選択してください。

  • autoは予約済みの名前で、他のものを使用することをお勧めします。

0

予想通り、私は

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

に自分のコードを更新OLES、 のおかげで、残念ながら、まだ何かが動作しません。私はfahrerloop内の削除を行うことはできません。これは、同時に変更を行うことで終了します。ここに掲載されたコードでは、それ以上の例外はありません。デバッグビューでは、最後のループの後に車のいずれかに残ったドライバがないことがわかります。特にid 2のドライバはドライバリストから削除されます。残念ながら、ドライバはデータベースに残っています。私は最後の答えを正しく理解していれば、そうではないはずです。

関連する問題