Spring wenn Repository liefert null

Dimax

Top Contributor
Guten Tag ,
Was macht man in Spring um NullPointer zu vermeiden , falls Repository null liefert?
Ich habe folgendes Repository:
Java:
@Repository
public interface ProgrammRepository extends JpaRepository<Programm,ProgrammPK>{

    @Query(value="select max(programm_id) from sco.programm" ,nativeQuery=true)
    int getMaxId();
}
Aber wenn ich noch keine Daten in der DB habe ,liefert es natürlich null.
Folgende code liefert mir deswegen Nullpointerexception:

Java:
int programm_id_int = progRepository.getMaxId()+1;
[/code]
There was an unexpected error (type=Internal Server Error, status=500).
Null return value from advice does not match primitive return type for: public abstract int scoSpring.repo.ProgrammRepository.getMaxId()
org.springframework.aop.AopInvocationException: Null return value from advice does not match primitive return type for: public abstract int scoSpring.repo.ProgrammRepository.getMaxId()
 
K

kneitzel

Gast
Evtl. noch als Hinweis:
ANSI SQL wäre die coalesce Methode wohl eine Möglichkeit. Dann hätte man etwas, das Datenbankübergreifend hoffentlich funktionieren wird.
 

Dimax

Top Contributor
Danke Jungs für sehr schnelle Hilfe, hab auf so was geändert und es läuft
Java:
@Query(value="select COALESCE(MAX(programm_id),0) from sco.programm" ,nativeQuery=true)
int getMaxId();
 

Dimax

Top Contributor
Wenn du ein Native Query verwendest
Ich habe native benutzt, weil ich habe es nicht geschafft vom Model die max id zu kriegen weil es bei mir multiple Primary key ist und in einer getrennte Klasse liegt.->
Code:
@Entity
@NamedQuery(name="Programm.findAll", query="SELECT p FROM Programm p")
public class Programm implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private ProgrammPK id;

    public Programm(ProgrammPK id, Timestamp hinzugefuegt, String programm) {
        super();
        this.id = id;
        this.hinzugefuegt = hinzugefuegt;
        this.programm = programm;
    }
und das ist die PrimaryKey classe
Java:
@Embeddable
public class ProgrammPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;
    
    @Column(name="projekt_id", insertable=false, updatable=false)
    private int projektId;
    
    @Column(name="programm_id")
    private int programmId;
    
    public ProgrammPK() {
        
    }
    
    public ProgrammPK(int projektId,int programmId) {
        this.projektId=projektId;
        this.programmId=programmId;
    }
Natürlich wäre besser vom PK classe max programm_id zu bekommen ,aber ich weis nicht wie.
 

mrBrown

Super-Moderator
Mitarbeiter
Just my two cents:

OptionalInt könnte auch klappen, dass wäre die bessere Wahl als Integer mit null.

Mit COALESCE musst du aufpassen und sicherstellen, dass 0 kein valider Wert ist, negative Zahlen solltest du dann wahrscheinlich ebenso ausschließen.

"die größte Id" ist in den meisten Fällen seehr merkwürdig, was willst du damit denn machen? Vielleicht gibt es einen deutlich sinnvolleren Weg. Eine ID sollte ja üblicherweise semantisch keine Zahl sein, sondern eben nur ein Identifier.
 

LimDul

Top Contributor
An der Stelle finde ich die Konstruktion mit einer eigenen ID Klasse, aber Max-Werten aus der DB fragwürdig.

Als PK sollte man entweder verwenden:
* Eine technische ID - am besten aus der DB per Sequence oder ähnlichem erzeugt
* Eine fachliche ID, die aus der Anwendung kommt

Das hier sieht etwas nach einem Mix aus beiden aus, weswegen man da eine maximale ID aus der DB braucht. Bei so Eigenbaulösungen "Lese maximale ID aus der DB, erhöhe um 1" läuft man extrem schnell in Probleme rein, die gemeinerweise im Test kaum auftreten. Probleme, die da schnell entstehen:
* Was ist wenn es zwei Instanzen der Anwendung (per Load-Balancer) gibt, die auf die gleiche DB zu greifen? Da wird das lustig mit den Caches von Hibernate und Co.
* was ist, wenn es mehrere Threads gibt, die gleichzeitig ein neues Objekt anlegen wollen? Da können schnell Race Conditions entsehen.

Daher würde ich tatsächlich mal hinterfragen: Wofür braucht man die maximale ID? Entweder sollte das ein fachlicher Schlüssel sein - dann brauche ich keine maximale ID. Oder es ist ein technischer - dann sollte es Aufgabe der DB sein mir den nächsten verfügbaren zu geben.
 
K

kneitzel

Gast
Wenn man die Id selbst ermitteln will und dazu eine gewisse Logik aufbaut, die außerhalb der DB liegt und lediglich den Max-Wert abfragt, dann bekomme ich da immer Bauschschmerzen.

Was ist, wenn da mehrere Threads sowas versuchen? Dann sehen beide, dass Max von mir aus 5 ist um dann die 6 zu nutzen?

Aber die genaue Logik, die verwendet wurde, ist ja nicht bekannt. Daher kann man da natürlich nichts sagen. Und evtl. findet ja auch alles in einer Transaktion statt, die gewisse Teile der Datenbank dann auch sperrt um sowas zu vermeiden?

Aber in der Beziehung hätte ich hier eher meine Sorgen muss ich gestehen.
 

Dimax

Top Contributor
Ich muss beim Programmspeichern max id ermitteln. Oder wie macht man sowas?
Java:
int programm_id_int=0;
programm_id_int = progRepository.getMaxId()+1;
ProgrammPK programmPK=new ProgrammPK(projekt_Id,programm_id_int);
Programm programm=new Programm(programmPK,new Timestamp(System.currentTimeMillis()),progra_name);
progRepository.save(programm);
 
K

kneitzel

Gast
Die Id würde ich der Datenbank überlassen. Dann würdest Du lediglich ein Programm haben, bei dem die programm_id null / 0 ist (Halt den Wert, der signalisiert, dass die id noch nicht vergeben wurde). Beim Speichern wird dann die Datenbank die id vergeben und die id lässt man sich dann beim Speichern auch zurück geben und trägt dies dann in seiner Entity ein. Das findet dann aber innerhalb des Repositories statt.

Das wäre so ein Vorgehen, das man verwenden könnte. Wenn das ProgramPK eine entsprechende Entity ist, dann kann das schon entsprechend sein - das finde ich gerade etwas verwirrend - für einen zusammengesetzten PK habe ich eigentlich keine eigene Entity - ist das auf Datenbankseite auch so abgebildet, dass das eine eigene Klasse ist?
 

Dimax

Top Contributor
Die Modelle wurden automatisch so generiert. Ich habe die nur erweitert. Autoinkrement auf programm_id zu setzen kann ich auch nicht. Die Programme gehören in der DB immer zu einem Projekt und beim löschen von Projekten, werden auch die dazugehörige Programme mit gelöscht.
Also wie ist es am besten zu lösen wenn es kein autoinkrement für programm_id möglich ist und wie bekommt man in dem Fall die max id vom Modell und nicht von der DB mit nativeQuerry?
 
K

kneitzel

Gast
Also erst einmal ist der Weg technisch so möglich (Egal wie unschön das so ist).

So ein unique index das Insert vorhandener Programm_id Werte verhindert, kann man das so bauen.
Dann willst Du aber den Fall abfangen, dass die programm_id schon vorhanden ist -> um dann ein Insert ggf. erneut zu probieren.
 

Dimax

Top Contributor
Sequence auf DB-Seite möglich
Wenn ich dich richtig verstanden habe du meinst autoincrement? Wenn ja ,dann geht nicht nativ(mehrere andere Tabelen wo diese id als Teil des PK ist..zmb(
Java:
@Embeddable
public class QuelltextPK implements Serializable {
    //default serial version id, required for serializable classes.
    private static final long serialVersionUID = 1L;

    @Column(name="projekt_id", insertable=false, updatable=false)
    private int projektId;

    @Column(name="programm_id", insertable=false, updatable=false)
    private int programmId;

    @Column(name="zeilen_nr")
    private int zeilenNr;
)
wie es emuliert geht kenne ich nicht und deswegen nicht ausprobiert.
 

mrBrown

Super-Moderator
Mitarbeiter
Wenn ich dich richtig verstanden habe du meinst autoincrement? Wenn ja ,dann geht nicht nativ(mehrere andere Tabelen wo diese id als Teil des PK ist..zmb(
Nein, AUTO_INCREMENT ist was anderes.

Ob die ID irgendwo als Fremdschlüssel benutzt wird, ist dafür aber völlig egal. Wenn es eine Programm-Tabelle gibt, kann die programmId trotzdem "AUTO_INCREMENT" sein.


Mit Sequence meinte ich sowas: https://docs.microsoft.com/de-de/sq...e-sequence-transact-sql?view=sql-server-ver15
MySQL kann es nativ afaik nicht, daher muss man es dort nachbauen.
 

Dimax

Top Contributor
Hab es auf AI gestzt mit SET FOREIGN_KEY_CHECKS = 0; und after update wieder auf SET FOREIGN_KEY_CHECKS = 1;
So Jetzt habe programm_id autoincrement..dan muss ich doch Alle Modelle ändern?
 

Dimax

Top Contributor
Hm..dann brauche ich aber die getGeneratedKeys(); fur alle andere Modelle..hm ..Wie kriegt man aber sowas vom Model?
 

Dimax

Top Contributor
Nur das Model, wo es wirklich Teil der ID
Ich habe 11 Modelle ,wo es wirklich ein Teil der Id ist)) Und nachdem ich das Program gespeichert habe muss ich die programm_id kennen für die restlichen Tabellen.Das ging mit einfachen Java db drivers mit Statement.getGeneratedKeys() wie es in Spring geht muss ich nachschauen.
 

mrBrown

Super-Moderator
Mitarbeiter
Ich habe 11 Modelle ,wo es wirklich ein Teil der Id ist)) Und nachdem ich das Program gespeichert habe muss ich die programm_id kennen für die restlichen Tabellen.Das ging mit einfachen Java db drivers mit Statement.getGeneratedKeys() wie es in Spring geht muss ich nachschauen.
Du solltest den restlichen Teil des Satzes nicht ignorieren: "und nicht als Fremdschlüssel benutzt wird."

In QuelltextPK ist es zB ein Fremdschlüssel.
 

Dimax

Top Contributor
Ich habe programmRepo modifiziert:
Java:
@Repository
public interface ProgrammRepository extends JpaRepository<Programm,ProgrammPK>{
@Query(value="select last_insert_id() from sco.programm" ,nativeQuery=true)
    int getLastId();
}
und im Controller nach dem insert für andere Tabelen :
Java:
progRepository.save(programm);
programm_id_int = progRepository.getLastId();
for (int i = 0; i < Werte.length - 1; i++) {
            QuelltextPK quellPK = new QuelltextPK(projekt_Id,programm_id_int,i + 1);
            Quelltext quel=new Quelltext(quellPK,Werte[i][1]);
            quellRepository.save(quel);
            }
Feng-Shui ?
 

Oneixee5

Top Contributor
Generell ist max(ID) keine gute Lösung aber wenn es nicht anders geht:
Java:
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

    @Autowired
    private EmployeeRepositry repo;

    public static void main(final String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    public void run(final String... args) throws Exception {
        final Employee e1 = new Employee();
        e1.setFirstName("Krishna");
        e1.setLastName("Gurram");
        this.repo.save(e1);

        System.out.println(e1.getId());

        final Employee e2 = new Employee();
        e2.setFirstName("Dalai");
        e2.setLastName("Lama");
        this.repo.save(e2);
        System.out.println(e2.getId());
    }

}
Java:
@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue(generator = "max-generator")
    @GenericGenerator(name = "max-generator", strategy = "com.example.demo.EmployeeGenerator")
    @Column(name = "ID")
    private int id;

    private String firstName;

    private String lastName;

    public int getId() {
        return this.id;
    }

    public void setId(final int id) {
        this.id = id;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(final String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(final String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Employee [id=" + this.id + ", firstName=" + this.firstName + ", lastName=" + this.lastName + "]";
    }

}
Java:
public class EmployeeGenerator implements IdentifierGenerator, Configurable {

    @Override
    public Serializable generate(final SharedSessionContractImplementor session, final Object obj)
            throws HibernateException {
        final Object id = session.createQuery("select max(e.id) + 1 from Employee e").getSingleResult();
        if (id == null) {
            return Integer.valueOf(1);
        }
        return Integer.valueOf(((Number) id).intValue());
    }

    @Override
    public void configure(final Type type, final Properties properties, final ServiceRegistry serviceRegistry)
            throws MappingException {
        // properties.getProperty for possible parameters
    }

}
Java:
@Repository
public interface EmployeeRepositry extends JpaRepository<Employee, Integer> {

}

EmployeeGenerator übernimmt dabei die Abfrage und Generierung der ID. Grundsätzlich kann man das auch so aufbauen, dass es generisch für verschiedene Typen verwendbar ist. Es wird dann nur sehr unübersichtlich.
 

Oneixee5

Top Contributor
Das funktioniert auch mit Compound-Keys:

Java:
@SpringBootApplication
public class DemoApplication implements CommandLineRunner {

    @Autowired
    private EmployeeRepositry repo;

    public static void main(final String[] args) {
        SpringApplication.run(DemoApplication.class, args);
    }

    @Override
    public void run(final String... args) throws Exception {
        final Employee e1 = new Employee();
        e1.setFirstName("Krishna");
        e1.setLastName("Gurram");
        this.repo.save(e1);
        System.out.println(e1.getId());

        final Employee e2 = new Employee();
        e2.setFirstName("Dalai");
        e2.setLastName("Lama");

        final EmployeePK pk = new EmployeePK();
        pk.setLabel("test");
        e2.setId(pk);

        this.repo.save(e2);
        System.out.println(e2.getId());
    }

}
Java:
package com.example.demo;

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

import org.hibernate.annotations.GenericGenerator;

@Entity
@Table(name = "EMPLOYEE")
public class Employee {

    @Id
    @GeneratedValue(generator = "max-generator")
    @GenericGenerator(name = "max-generator", strategy = "com.example.demo.EmployeeGenerator")
    @Column(name = "ID")
    private EmployeePK id;

    private String firstName;

    private String lastName;

    public EmployeePK getId() {
        return this.id;
    }

    public void setId(final EmployeePK id) {
        this.id = id;
    }

    public String getFirstName() {
        return this.firstName;
    }

    public void setFirstName(final String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return this.lastName;
    }

    public void setLastName(final String lastName) {
        this.lastName = lastName;
    }

    @Override
    public String toString() {
        return "Employee [id=" + this.id + ", firstName=" + this.firstName + ", lastName=" + this.lastName + "]";
    }

}
Java:
public class EmployeeGenerator implements IdentifierGenerator, Configurable {

    @Override
    public Serializable generate(final SharedSessionContractImplementor session, final Object obj)
            throws HibernateException {
        EmployeePK pk = ((Employee) obj).getId();
        if (pk == null) {
            pk = new EmployeePK();
            pk.setLabel("default");
        } else {
            pk = ((Employee) obj).getId();

        }
        final Object id = session.createQuery("select max(e.id.id) + 1 from Employee e").getSingleResult();
        if (id == null) {
            pk.setId(1);
        } else {
            pk.setId(((Number) id).intValue());
        }
        return pk;
    }

    @Override
    public void configure(final Type type, final Properties properties, final ServiceRegistry serviceRegistry)
            throws MappingException {
        // properties.getProperty for possible parameters
    }

}
Java:
@Embeddable
public class EmployeePK implements Serializable {

    private int id;
    private String label;

    public int getId() {
        return this.id;
    }

    public void setId(final int id) {
        this.id = id;
    }

    public String getLabel() {
        return this.label;
    }

    public void setLabel(final String label) {
        this.label = label;
    }

    @Override
    public String toString() {
        return "EmployeePK [id=" + this.id + ", label=" + this.label + "]";
    }

}
 

Dimax

Top Contributor
Das funktioniert auch mit Compound-Keys
Ich danke dir für die Beispiele .Ich weiß, dass du mir etwas zeigen willst, was sehr nützlich sein soll ,aber ich verstehe nicht was. Es ist genau so wie die Aussage von mrBrown ,wegen Tutorial gucken. Ich weiß ,dass ich sehr viele Fehler mache , aber weswegen ich Tutorials angucken soll und welche verstehe ich nicht. Ich habe sehr viele geguckt und sogar von baeldung.com Spring Data JPA: The Certification Class bezahlt und zu 60% durchgemacht. Leute ich bin kein Profi in Spring, ich lerne erst gerade. Jetziger Stand ist dass ich die programmId autoinkrement in der DB gemacht habe ,und direkt nach dem Inserten generierte id mit der Querry @Query(value="select last_insert_id() from sco.programm" ,nativeQuery=true) für die nachfolgende Tabellen ermittle und speichere.
 

mrBrown

Super-Moderator
Mitarbeiter
Es ist genau so wie die Aussage von @mrBrown ,wegen Tutorial gucken. Ich weiß ,dass ich sehr viele Fehler mache , aber weswegen ich Tutorials angucken soll und welche verstehe ich nicht. Ich habe sehr viele geguckt und sogar von baeldung.com Spring Data JPA: The Certification Class bezahlt und zu 60% durchgemacht. Leute ich bin kein Profi in Spring, ich lerne erst gerade.
Das "Warum" ist einfach: du hast, plump ausgedrückt, keine Ahnung, was du dort machst.

Ein spezifisches Tutorial kann ich dir nicht empfehlen, "Spring Data JPA: The Certification Class" klingt aber zumindest dem Titel nach nicht völlig falsch. Wenn du aber wirklich 60% gemacht hast und trotzdem dieser Code bei raus kommt ist der Kurs sein Geld nicht wert...


Für den "richtigen" Weg solltest du dir mal angucken, was die save-Methode so zurückgibt, und warum sie das macht. Ein "last_insert_id" ist da keinesfalls nötig, das macht JPA quasi alles automatisch.
 
K

kneitzel

Gast
Ich brauche last_insert_id um Quelltex und die restlichen 10 Tabellen zu befüllen , da wird nichts automatisch gemacht!
Also normalerweise hast du ja Entities. Beim Speichern Word die id in der gespeicherten Instanz gesetzt. Wenn du nun also die Id der gespeicherten Instanz irgendwo brauchst, dann kannst du diese da bekommen. (Siehe Code in #30)

Nach dem Speichern noch die Datenbank befragen kann böse enden. Wenn zwei Elemente parallel gespeichert werden, dann bekommen ggf. Beide Threads die gleich last inserted id.

Aber du hast in dem Datenmodel oft auch nicht fremde Ids sondern Referenzen. Daher brauchst Du auch die Id in der Regel nicht sondern du arbeitest mit der Instanz, die du dann zuweist.
 

mrBrown

Super-Moderator
Mitarbeiter
Ich brauche last_insert_id um Quelltex und die restlichen 10 Tabellen zu befüllen , da wird nichts automatisch gemacht!
Save gibt dir etwas zurück, dieses hat die automatisch generierte ID gesetzt. Das musst du nicht mehr selbst machen.

Und wenn du Beziehungen statt nur Composite Keys nutzt, macht JPA auch den Rest automatisch.


Das ist nichts, was man hier im Forum in Kürze erklären könnte, jedes Tutorial dazu sollte es aber eigentlich abdecken.


Wenn die Leute ohne Ahnung zu haben ,solche Programme schreiben können ,was passiert wenn die ein Tutorial dazu gucken?)))
"solche Programme" heißt in diesem Fall etwas nicht funktionierendes, sonst gäb's hier ja keine Fragen ;)

Das "keine Ahnung" war auch nicht böse gemeint, dass sollte einfach nur eine stumpfe Feststellung sein, da du eben nicht genau weißt, wie man mit JPA arbeitet – ein gutes Tutorial würde da helfen, oder alternativ jemand, der es dir erklärt (falls du grad eine Ausbildung oder Studium machst)
 

Dimax

Top Contributor
final Object id = session.createQuery("select max(e.id.id) + 1 from Employee e").getSingleResult();
Hier wird das Model angesprochen, das letztendlich auch die max id von der DB hollen soll.Die Frage:lohnt es sich soviel Aufwand wegen dem was auch das hier macht?:->
Java:
@Query(value="select COALESCE(MAX(programm_id),0) from sco.programm" ,nativeQuery=true)
int getMaxId();
Das "keine Ahnung" war auch nicht böse gemeint
Das war ein wenig übertrieben aber egal, hab keine Probleme damit.
 

LimDul

Top Contributor
Danke ,das wusste ich nicht. Aber vor dem ersten Speichern brauche ich doch die Id,die ich mit der DB klären soll. Auch wie Oneixee5 zeigt das Objekt könnte man generieren ,nur vor dem allerersten speichern muss ich doch die Id von der DB holen?
Nö, die ID brauchst du in der Regel nicht. Wozu?

Die ID dient in der Regel nur dazu, die Beziehungen in der DB zu speichern (das übernimmt aber alles JPA) und Objekte technisch zu identifizieren, wenn sie einmal gespeichert sind. Dementsprechend braucht mit die ID - wenn überhaupt - erst nach dem speichern.
 

mrBrown

Super-Moderator
Mitarbeiter
Danke ,das wusste ich nicht. Aber vor dem ersten Speichern brauche ich doch die Id,die ich mit der DB klären soll. Auch wie @Oneixee5 zeigt das Objekt könnte man generieren ,nur vor dem allerersten speichern muss ich doch die Id von der DB holen?
Vor dem ersten Speichern gibt es in der DB keine ID. Da steht das Object doch noch nicht in der DB, wie soll es dann dort eine ID haben?
 

Dimax

Top Contributor
Save gibt dir etwas zurück
Code:
ProgrammPK programmPK=new ProgrammPK(projekt_Id);
Programm programm=new Programm(programmPK,new Timestamp(System.currentTimeMillis()),progra_name);
int programm_id_int=progRepository.save(programm).getId().getProgrammId();
System.out.println("programm_id_int="+programm_id_int);
programm_id_int=0
2021-08-27 12:20:59.808 WARN 11400 --- [nio-8080-exec-9] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 1452, SQLState: 23000
Programm id ist in der DB autoincrement..warum liefert save 0 obwohl in der DB wir es richtig gespeichert?
 

LimDul

Top Contributor
Da fehlt die Id-Annotation:

The GeneratedValue annotation may be applied to a primary key property or field of an entity or mapped superclass in conjunction with the Id annotation. The use of the GeneratedValue annotation is only required to be supported for simple primary keys. Use of the GeneratedValue annotation is not supported for derived primary keys.

Sofern das kein echtes Praxis Projekt ist - verzichte auf den Composite Primary Key und nimmt einfache, technische Ids vom Typ Long. Das was du da versuchst zu bauen ist architektonisch gelinde gesagt Unfug.

Entweder es gibt eine Primary Key Spalte, die aus der Datenbank generiert wird (ID+GeneratedValue) dran
ODER
es gibt einen Primary Key, der komplett fachlich ist und nicht auf irgendwelche Datenbank-IDs beruht.

Du vermischst das gerade und hast so das schlechteste aus beiden Welten.
 

Dimax

Top Contributor
Da fehlt die Id-Annotation:
Also, you must not use @Id within an @Embeddable. I thus created a seperate.
Sofern das kein echtes Praxis Projekt ist - verzichte auf den Composite Primary Key
Leides ist es und es geht nicht ohne Composite Primary Key weil jedes Programm gehört zu bestimmten Projekt und alle von restlichen Tabellen gehören zu irgendeinem Programm von irgendeinem Projekt um das Löschen zu kaskadieren.
 

LimDul

Top Contributor
Leides ist es und es geht nicht ohne Composite Primary Key weil jedes Programm gehört zu bestimmten Projekt und alle von restlichen Tabellen gehören zu irgendeinem Programm von irgendeinem Projekt um das Löschen zu kaskadieren.
Ich sehe da den Grund nicht, es sei denn jemand hat ein komplett falsches Datenmodell gebaut.

Jedes Objekt hat einen Primary Key - ID vom Typ Long.
Wenn ein Programm zu einem Projekt gehört, dann gibt es einen Foreign Key von Programm => Projekt (der diese technischen IDs) nutzt.

Ein Primary Key dient dazu ein Objekt zu identifizieren - und nicht zu sagen "Das gehört aber zu X". Das sind Foreign Keys. Wenn möglich, zeig mal dein Datenbank Schema mit Beziehungen zwischen den Tabellen - bzw. dein fachliches Datenmodell.
 

Dimax

Top Contributor
Wenn möglich, zeig mal dein Datenbank Schema mit Beziehungen zwischen den Tabellen
Als Beispiel 3 Tabellen
Code:
CREATE TABLE `projekt` (
  `projekt` varchar(128) NOT NULL,
  `projekt_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `hinzugefuegt` timestamp NULL DEFAULT NULL,
  `beschreibung` varchar(128) DEFAULT NULL,
  PRIMARY KEY (`projekt_id`),
  UNIQUE KEY `projekt_id_UNIQUE` (`projekt_id`)
) ENGINE=InnoDB AUTO_INCREMENT=205 DEFAULT CHARSET=utf8 COMMENT='Schlüsseltabelle für Projekte';

CREATE TABLE `programm` (
  `programm_id` smallint(5) unsigned NOT NULL AUTO_INCREMENT,
  `projekt_id` smallint(5) unsigned NOT NULL,
  `hinzugefuegt` timestamp NULL DEFAULT NULL,
  `programm` varchar(32) DEFAULT 'empty',
  PRIMARY KEY (`programm_id`,`projekt_id`),
  KEY `programm_projekt_idx` (`projekt_id`),
  KEY `mdaten_programm_idx` (`projekt_id`,`programm_id`),
  CONSTRAINT `programm_projekt` FOREIGN KEY (`projekt_id`) REFERENCES `projekt` (`projekt_id`) ON DELETE CASCADE
) ENGINE=InnoDB AUTO_INCREMENT=66 DEFAULT CHARSET=utf8 COMMENT='Schlüsseltabelle für Programme';

CREATE TABLE `quelltext` (
  `projekt_id` smallint(5) unsigned NOT NULL,
  `programm_id` smallint(5) unsigned NOT NULL,
  `zeilen_nr` smallint(6) unsigned NOT NULL DEFAULT '0',
  `zeilen_inhalt` text,
  PRIMARY KEY (`projekt_id`,`programm_id`,`zeilen_nr`),
  KEY `quelltext_programm_idx` (`projekt_id`,`programm_id`),
  CONSTRAINT `quelltext_programm` FOREIGN KEY (`projekt_id`, `programm_id`) REFERENCES `programm` (`projekt_id`, `programm_id`) ON DELETE CASCADE ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='1:1 Kopie des Original Quelltextes inklusive Zeilennummer';
 

LimDul

Top Contributor
Dann mach programm_id zum Primary Key und fertig. Warum muss da noch projekt_:id als PK rein? Das ist fachlich kompletter Unfug.

Das Cascade Delete funktioniert ja über den FK, nicht über den FK:

Eine Spalte, die gleichzeitig Teil eines PK und ein FK ist halte ich fachlich falsch.
 
Ähnliche Java Themen
  Titel Forum Antworten Datum
8u3631984 Ist es möglich in Spring Entity generische Listen verwenden Frameworks - Spring, Play, Blade, Vaadin & Co 3
R Spring Boot Test Assertions mit Objekten Frameworks - Spring, Play, Blade, Vaadin & Co 6
8u3631984 Pfad zu Test Datei in application.yml in Spring Boot Test Frameworks - Spring, Play, Blade, Vaadin & Co 7
R Spring Boot sql Beziehungen Frameworks - Spring, Play, Blade, Vaadin & Co 12
8u3631984 Spring JPA Probleme beim SPeichern von Sets Frameworks - Spring, Play, Blade, Vaadin & Co 3
M Spring Boot 3 Datenbanken zur Laufzeit Verbinden Frameworks - Spring, Play, Blade, Vaadin & Co 5
8u3631984 Spring JDBC Probleme beim Spaltennamen Frameworks - Spring, Play, Blade, Vaadin & Co 3
LimDul Spring-Batches in Docker über Rest starten/verfolgen Frameworks - Spring, Play, Blade, Vaadin & Co 0
ExceptionOfExpectation In Meiner Spring-Boot Applikation verlangt die Datenbank Wert für eine ID Frameworks - Spring, Play, Blade, Vaadin & Co 5
H Spring Boot Applikation und JHM Benchmark sowie ContextConfiguration in H2 Tests ich bekomme es nicht hin Frameworks - Spring, Play, Blade, Vaadin & Co 2
ExceptionOfExpectation Tests in Spring-Boot Frameworks - Spring, Play, Blade, Vaadin & Co 4
R Eure Erfahrungen mit Primefaces und Spring - wer managed die Beans Frameworks - Spring, Play, Blade, Vaadin & Co 4
Avalon Get Request doppelt abfeuern ohne Post Redirect Get Pattern. Spring Boot Thymeleaf MVC Frameworks - Spring, Play, Blade, Vaadin & Co 12
thor_norsk Konfigurationsprobleme mit Spring Boot Frameworks - Spring, Play, Blade, Vaadin & Co 9
R Spring Boot Integration-testing mit Keycloak Frameworks - Spring, Play, Blade, Vaadin & Co 1
R Spring Boot Integration-testing mit Keycloak Frameworks - Spring, Play, Blade, Vaadin & Co 13
L Spring Data und Rest Controller? Frameworks - Spring, Play, Blade, Vaadin & Co 4
thor_norsk Spring Boot Fehler Frameworks - Spring, Play, Blade, Vaadin & Co 1
L Spring Data und Rest Conroller? Frameworks - Spring, Play, Blade, Vaadin & Co 4
thor_norsk Spring Boot und Docker Frameworks - Spring, Play, Blade, Vaadin & Co 5
B Spring Amazon-SP-Api Frameworks - Spring, Play, Blade, Vaadin & Co 3
8u3631984 Aktualisiere Spring Controller Frameworks - Spring, Play, Blade, Vaadin & Co 4
L Spring Data: Modellierung mit einer Embeddable bean Frameworks - Spring, Play, Blade, Vaadin & Co 2
D Spring Boot Test ob Validation geprüft wurde Frameworks - Spring, Play, Blade, Vaadin & Co 8
K Spring Boot OneToMany Frameworks - Spring, Play, Blade, Vaadin & Co 6
8u3631984 Spring Boot Docker Image erstellen und mit docker-compose konfigurieren Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Wann Spring Batch nutzen? Frameworks - Spring, Play, Blade, Vaadin & Co 1
P Spring Hessian Remote Beispiel Frameworks - Spring, Play, Blade, Vaadin & Co 20
8u3631984 Spring 2.7.8 Info Enpoint nicht zuerreichen Frameworks - Spring, Play, Blade, Vaadin & Co 1
gradlew.bat spring-boot:run funktioniert nicht Frameworks - Spring, Play, Blade, Vaadin & Co 4
Zrebna Spring Boot/Thymeleaf: Bestätigungsemail senden. Frameworks - Spring, Play, Blade, Vaadin & Co 2
Zrebna Spring - Thymeleaf: Wieso wird gem. Fallunterscheidung entsprechende View nicht geladen? Frameworks - Spring, Play, Blade, Vaadin & Co 3
Dimax Spring UsernameNotFoundException(msg); auf der View msg ausdrücken Frameworks - Spring, Play, Blade, Vaadin & Co 1
Dimax Spring UsernameNotFoundException(Message) auf der View Message ausdrücken Frameworks - Spring, Play, Blade, Vaadin & Co 2
B Spring Boot und JPA Error creating bean Frameworks - Spring, Play, Blade, Vaadin & Co 24
R Spring Security: Wie kommt 'UserDetails' an Username und Passwort ran? Frameworks - Spring, Play, Blade, Vaadin & Co 6
R Spring Security: Wie den User dynamisch authentifizieren? Frameworks - Spring, Play, Blade, Vaadin & Co 8
R Spring Security: Authentication & Permissions Frameworks - Spring, Play, Blade, Vaadin & Co 4
R Spring Boot: Warum soll PasswordEncoder in einer neuen Methode definiert sein? Frameworks - Spring, Play, Blade, Vaadin & Co 1
8u3631984 Cross-Origin beim Abrufen von Spring Endpoint Frameworks - Spring, Play, Blade, Vaadin & Co 1
D Spring Boot und Microservices Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Spring Boot additional Datasource for a single entity Frameworks - Spring, Play, Blade, Vaadin & Co 0
T Spring Resourcen Ordner ermitteln Frameworks - Spring, Play, Blade, Vaadin & Co 5
B Spring JPA und Repository Frameworks - Spring, Play, Blade, Vaadin & Co 12
D Mapstruct Dependency Injection funktioniert nicht mit Spring Frameworks - Spring, Play, Blade, Vaadin & Co 15
Avalon Wie sieht bei Euch das Deployment einer Spring Boot Anwendung aus? Frameworks - Spring, Play, Blade, Vaadin & Co 4
M Threads in Spring Boot Frameworks - Spring, Play, Blade, Vaadin & Co 7
W DI-Problem in Spring Boot Frameworks - Spring, Play, Blade, Vaadin & Co 4
T Spring Boot: Was bewirkt parent in maven genau? Frameworks - Spring, Play, Blade, Vaadin & Co 4
T Spring Security: Run-as replacement Einsatzbereich? Frameworks - Spring, Play, Blade, Vaadin & Co 1
OnDemand Vaadin+Spring Boot erster Seitenload nach Neustart endlos Frameworks - Spring, Play, Blade, Vaadin & Co 0
doncarlito87 Wie erhalte ich ein JSON aus eine NativeQuery (Spring Boot)? Frameworks - Spring, Play, Blade, Vaadin & Co 8
Avalon @Query Select Abfrage liefert falsche Werte (Spring Boot, JPA, Hibernate) Frameworks - Spring, Play, Blade, Vaadin & Co 3
Avalon Erstellung Dockerimage mit spring-boot:build-image in Spring Boot mit Umgebungsvariablen Frameworks - Spring, Play, Blade, Vaadin & Co 0
N Spring Integration - Logging Frameworks - Spring, Play, Blade, Vaadin & Co 7
D Spring Boot Field Injection in MapStruct Frameworks - Spring, Play, Blade, Vaadin & Co 5
D Spring Anfänger benötigt Hilfe Frameworks - Spring, Play, Blade, Vaadin & Co 9
OnDemand Spring Boot seltsame Logeinträge: Manipulationsversuche? Frameworks - Spring, Play, Blade, Vaadin & Co 2
D Spring Date keine neue Tabelle fuer Attribut Frameworks - Spring, Play, Blade, Vaadin & Co 1
T Spring Security Config File anpassen Frameworks - Spring, Play, Blade, Vaadin & Co 1
8u3631984 Spring Cloud : Resttemplate mit Loadballancer Frameworks - Spring, Play, Blade, Vaadin & Co 11
Dimax Spring resource not found Frameworks - Spring, Play, Blade, Vaadin & Co 2
M Spring MongoDB unique index Frameworks - Spring, Play, Blade, Vaadin & Co 3
M Spring Entity testen Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Spring Entity testen Frameworks - Spring, Play, Blade, Vaadin & Co 5
Dimax Spring App Probleme beim Ausführen auf dem Tomcat Server Frameworks - Spring, Play, Blade, Vaadin & Co 1
D Spring WebFlux Cors konfigurieren Frameworks - Spring, Play, Blade, Vaadin & Co 1
Dimax Schöne View mit anchor scrolling in Spring Frameworks - Spring, Play, Blade, Vaadin & Co 2
Dimax Spring JPA Multiple Keys Frameworks - Spring, Play, Blade, Vaadin & Co 3
S Spring Security mit oauth2 in lokaler Konfiguration principal mocken Frameworks - Spring, Play, Blade, Vaadin & Co 0
D Spring Boot Mile Stone und Snapshot Versionen Frameworks - Spring, Play, Blade, Vaadin & Co 2
OnDemand Spring Boot Exception Body Frameworks - Spring, Play, Blade, Vaadin & Co 2
D Was ist das Framework "Spring"? Frameworks - Spring, Play, Blade, Vaadin & Co 1
M Spring Unit/Integrations Testing Frameworks - Spring, Play, Blade, Vaadin & Co 3
D Spring Unit Test: UnsatisfiedDependencyException: Error creating bean with name Frameworks - Spring, Play, Blade, Vaadin & Co 2
H Resource Liste Lazy Autowired Spring Context Frameworks - Spring, Play, Blade, Vaadin & Co 2
M Java Spring Security Frameworks - Spring, Play, Blade, Vaadin & Co 5
M Spring Security Login with Credentials Frameworks - Spring, Play, Blade, Vaadin & Co 0
N Spring Boot - Overkill für private Projekte? Frameworks - Spring, Play, Blade, Vaadin & Co 3
krgewb Spring und GWT - & wird zu & amp; Frameworks - Spring, Play, Blade, Vaadin & Co 2
K Migration eines internen Frameworks zu Spring:Boot Frameworks - Spring, Play, Blade, Vaadin & Co 0
OnDemand JPA/Spring Repository Like Suche leeres Ergebnis Frameworks - Spring, Play, Blade, Vaadin & Co 0
Z Hibernate & Postgres in Spring Boot (Syntaxprobleme) Frameworks - Spring, Play, Blade, Vaadin & Co 2
Z Spring Boot mit JPA;, Hibernate, Rest & Lombok Frameworks - Spring, Play, Blade, Vaadin & Co 8
M Spring Initializer - Webservices Frameworks - Spring, Play, Blade, Vaadin & Co 0
D Spring Hateoas Frameworks - Spring, Play, Blade, Vaadin & Co 1
ma095 Spring und Postgresql Errors Frameworks - Spring, Play, Blade, Vaadin & Co 4
OnDemand Spring+Vaadin App startet nicht Frameworks - Spring, Play, Blade, Vaadin & Co 1
OnDemand Spring Request externe API SSL Error Frameworks - Spring, Play, Blade, Vaadin & Co 7
OnDemand Spring Repo speichert, aber es kommt in der DB nicht an Frameworks - Spring, Play, Blade, Vaadin & Co 3
Dimax Im Spring ,Mysql-Funktion aufrufen Frameworks - Spring, Play, Blade, Vaadin & Co 2
OnDemand Spring Security/Boot/Vaadin Cookie Problem bei iFrame Frameworks - Spring, Play, Blade, Vaadin & Co 4
OnDemand Spring Boot: Feld ignorieren Frameworks - Spring, Play, Blade, Vaadin & Co 3
8u3631984 Spring + Thymleaf : Checkbox Object mappen Frameworks - Spring, Play, Blade, Vaadin & Co 0
N Buch zum Spring Framework bzw. Spring Boot Frameworks - Spring, Play, Blade, Vaadin & Co 3
OnDemand Jasypt Spring Boot HIbernate wie komme ich an den Key? Frameworks - Spring, Play, Blade, Vaadin & Co 4
8u3631984 Spring Boot im Docker Container - Logback wird nicht verwendet Frameworks - Spring, Play, Blade, Vaadin & Co 13
sascha-sphw Spring - Authentication object was not found Frameworks - Spring, Play, Blade, Vaadin & Co 3
8u3631984 Welches Spring Frontend Framework verwendet ihr und wie bzw wo ? Frameworks - Spring, Play, Blade, Vaadin & Co 7
8u3631984 Spring security - 403 bei Role Access Regel Frameworks - Spring, Play, Blade, Vaadin & Co 6

Ähnliche Java Themen

Neue Themen


Oben