JPA keine shared primary key

lusitano

Aktives Mitglied
Hallo Leute,
kann ir mal jemand meinen Fehler zeigen? In einer OneToOne beziehung sollen sich die Entitys den primary key teilen. Leider Bekomme ich nur folgende Fehlermeldung. Mir ist bewusst das ich den PK aus anwender als PK in anwenderRechte verwenden muss. Nur finde ich die Lösung nicht .
Schon mal Danke für eure Meinung.

Javascript:
Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [objects.anwender.AnwenderRechte.anwender]
    at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:90)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:120)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:192)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:726)
    ... 75 more

Klasse Anwender ohne getter setter
Code:
@Entity
@Table(name = "anwender")
public class Anwender implements Serializable {

    
    /**
     *
     */
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "anwender_generator") // PrimaryKey wird durch den generator erstellt
    @SequenceGenerator(name = "anwender_generator", sequenceName = "anwender_seq", allocationSize = 10) // anwender_generator erhält Tabell anwender_seq jeder Eintrag wird um +10 erhöht
    @Column(name = "anwenderID_PK", updatable = false, nullable = false) // Tabellename ist nicht updatebar und darf nicht null beinhalten
    private int anwenderID_PK;
    
    private String anwenderBenutzerKennung;
    private String anwenderVorname;
    private String anwenderNachname;
    private String anwenderBenutzerRolle;
    private String anwenderPasswort;
    private boolean anwenderIstAngemeldet;
    
    
    @OneToOne(mappedBy = "anwender", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private AnwenderRechte anwenderRechte;
    
    public Anwender(String anwenderBenutzerKennung, String anwenderVorname, String anwenderNachname,
            String anwenderBenutzerRolle, String anwenderPasswort, boolean anwenderIstAngemeldet, AnwenderRechte anwenderRechte) {
        this.anwenderBenutzerKennung = anwenderBenutzerKennung;
        this.anwenderVorname = anwenderVorname;
        this.anwenderNachname = anwenderNachname;
        this.anwenderBenutzerRolle = anwenderBenutzerRolle;
        this.anwenderPasswort = anwenderPasswort;
        this.anwenderIstAngemeldet = anwenderIstAngemeldet;
        this.anwenderRechte = anwenderRechte;
    }

    public Anwender() {
    }

Klasse AnwenderRechte ohne getter setter

Code:
@Entity
@Table(name = "anwenderRechte")
public class AnwenderRechte implements Serializable {

    /**
     *
     */
    private static final long serialVersionUID = 1L;

    @Id
    private int anwenderRechteID_PK;

    private boolean darfErstellen;
    private boolean darfLoeschen;
    private boolean darfUpdaten;
    private boolean darfLesen;

    private int anwenderID_FK;

    @OneToOne
    @MapsId
    private Anwender anwender;

    public AnwenderRechte(boolean darfErstellen, boolean darfLoeschen, boolean darfUpdaten, boolean darfLesen) {
        this.darfErstellen = darfErstellen;
        this.darfLoeschen = darfLoeschen;
        this.darfUpdaten = darfUpdaten;
        this.darfLesen = darfLesen;
    }

    public AnwenderRechte() {
    }

und den Button speichern in dem das ganze gespeichert wird.

Code:
AnwenderDAOImpl anwenderDAOImpl = new AnwenderDAOImpl();
        anwenderDAOImpl.AnwenderDAOImpl();
        AnwenderRechte anwenderRechte = new AnwenderRechte(true, true, true, true);
        
        Anwender anwender = new Anwender(benutzerKennung, vorname, nachname, benutzerRolle, passwort, true, anwenderRechte);
        anwender.getAnwenderRechte().setAnwenderRechteID_PK(anwender.getAnwenderID_PK());
 
Leider nein.
Ich hab das jetzt noch ausprobiert.

Code:
    AnwenderDAOImpl anwenderDAOImpl = new AnwenderDAOImpl();
        anwenderDAOImpl.AnwenderDAOImpl();
      
        AnwenderRechte anwenderRechte = new AnwenderRechte();
        anwenderRechte.setDarfErstellen(true);
        anwenderRechte.setDarfLesen(true);
        anwenderRechte.setDarfLoeschen(true);
        anwenderRechte.setDarfUpdaten(true);
        
        Anwender anwender = new Anwender();
        anwenderRechte.setAnwenderRechteID_PK(anwender.getAnwenderID_PK());
        anwender.setAnwenderRechte(anwenderRechte); // Editiert
        anwender.setAnwenderBenutzerKennung(benutzerKennung);
        anwender.setAnwenderBenutzerRolle(benutzerRolle);
        anwender.setAnwenderIstAngemeldet(true);
        anwender.setAnwenderNachname(nachname);
        anwender.setAnwenderPasswort(passwort);
        anwender.setAnwenderVorname(vorname);
        
        
        anwenderDAOImpl.createAnweder(anwender);

Das funktioniert leider auch nicht.

Code:
Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [objects.anwender.AnwenderRechte.anwender]
    at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:90)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:120)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:192)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:726)
    ... 75 more
 
Auch nicht.
Code:
        AnwenderDAOImpl anwenderDAOImpl = new AnwenderDAOImpl();
        anwenderDAOImpl.AnwenderDAOImpl();
      
        AnwenderRechte anwenderRechte = new AnwenderRechte();
        anwenderRechte.setDarfErstellen(true);
        anwenderRechte.setDarfLesen(true);
        anwenderRechte.setDarfLoeschen(true);
        anwenderRechte.setDarfUpdaten(true);
        
        Anwender anwender = new Anwender();
        anwender.setAnwenderRechte(anwenderRechte);
        anwender.setAnwenderBenutzerKennung(benutzerKennung);
        anwender.setAnwenderBenutzerRolle(benutzerRolle);
        anwender.setAnwenderIstAngemeldet(true);
        anwender.setAnwenderNachname(nachname);
        anwender.setAnwenderPasswort(passwort);
        anwender.setAnwenderVorname(vorname);
        
        
        anwenderDAOImpl.createAnweder(anwender);
Fehlermeldung weiterhin.

Code:
Caused by: org.hibernate.id.IdentifierGenerationException: attempted to assign id from null one-to-one property [objects.anwender.AnwenderRechte.anwender]
    at org.hibernate.id.ForeignGenerator.generate(ForeignGenerator.java:90)
    at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:120)
    at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:192)
    at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:135)
    at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:118)
    at org.hibernate.internal.SessionImpl.firePersist(SessionImpl.java:726)
    ... 75 more


und da gehen mir auch schon die Ideen aus. Darauf erstmal ne Kippe.
 
So. Ich hab jetzt den Anwender in die DB gespeichert (ohne anwenderRrechte) dann den wieder aus der DB geholt und danach die anwenderRrechte in den Anwender.
Es funktioniert nicht.
Aber das ist das Resultat.
Er schreibt mir sehr wohl den Anwender in die DB. 12738
wohl aber keine anwenderRechte

12739

Code zum erstellen der Objekte,
Code:
  AnwenderRechte anwenderRechte = new AnwenderRechte(true, true, true, true);
        Anwender anwender = new Anwender();
          anwender.setAnwenderBenutzerKennung(benutzerKennung);
          anwender.setAnwenderBenutzerRolle(benutzerRolle);
          anwender.setAnwenderIstAngemeldet(true);
          anwender.setAnwenderNachname(nachname);
          anwender.setAnwenderPasswort(passwort);
          anwender.setAnwenderVorname(vorname);
      
          anwenderDAOImpl.testCreateAnwender(anwender, anwenderRechte);
code zum speichern

Code:
em.getTransaction().begin();
        em.persist(anwender);
        em.getTransaction().commit();
        
        Query query = em.createQuery("Select anwender from Anwender anwender");

        Collection<Anwender> anwenderCollection;

        anwenderCollection = (Collection<Anwender>) query.getResultList();
        
        List<Anwender> anwenderListe = (List<Anwender>) anwenderCollection;
        
        Anwender anwenderNeu =  new Anwender();
        
        for (int i = 0; i < anwenderListe.size(); i++) {
            anwenderNeu = anwenderListe.get(i);
        }
        
        anwenderNeu.setAnwenderRechte(anwenderRechte);
        
        em.getTransaction();
        em.persist(anwenderNeu);
        em.getTransaction().commit();
 
Du sollst ja erst nur den Anwender speichern und dann die Rechte setzen und anschließend den Anwender updaten. Hintergrund: die Persist-Kaskade dürfte dafür sorgen, dass beim persist eines Anwenders versucht wird, erstmal die Rechte zu persistieren. Das würde aber voraussetzen, dass der Anwender eine ID hat, was zu dem Zeitpunkt noch nicht der Fall ist. Also: erstmal Anwender persistieren - ohne Rechte - dann hat er eine ID, dann Rechte setzen und Anwender updaten.
 
Ok, Ich mach das jetzt morgen, für heute reicht es mir.
Schreib dir hier morgen die Ergebnisse rein. In der Zeit werde ich noch mal bissel nachlesen.Das kann eigentlich keine Lösung sein das man zuerst die Elternklasse persistieren muss. (meine Bescheidene Meinung.)

Trotzdem Danke ich dir für die heutige Hilfe und die Ausdauer hier am Ball zu bleiben.
70c476d84935edc8c75d5c2685ad1cf1.jpg
 
.... eigentlich wollte ich ja für heute Schluss machen. Aber wie es halt so mal ist, ne. ....
Ich hab es und es läuft.
Wobei bestimmt man es noch etwas optimieren kann.
geändert habe ich folgendes
Klasse anwender
Code:
@JoinColumn(name = "anwenderRechteID_PK", nullable = false)  // JoinColumn wurde hinzugefügt
    private AnwenderRechte anwenderRechte;

Klasse anwenderRechte

Code:
@OneToOne(fetch = FetchType.LAZY, mappedBy = "anwenderRechte") // mappedBy  hinzugefügt
    private Anwender anwender;

aber das wohl wichtigste (so denke ich)
Klasse anwenderRechte
Code:
public Anwender getAnwender() {
        return anwender;
    }

    public void setAnwender(Anwender anwender) {
        this.anwender = anwender;
    }
um auf private Anwender anwender zugreifen zu können den....
man muss wohl
sowohl der Kindsklasse
Code:
 anwenderRechte.setAnwender(anwender);
die Elternklasse mitgeben. Also auch
Code:
 anwender.setAnwenderRechte(anwenderRechte);
umgekehrt

Das Ergebnis ist dann 12741 12742


Nochmal Danke an @mihe7 für die Mühe und Hilfe
 

Zurück
Oben