0

erzeugt Aktie Ich Verwendung Frühling CRUDRepository versucht, für das Einfügen neues Objekts in der Datenbank JPA Datenbank-Modell (User.java, UserInfo.java). Datenbankmodell beziehen sich auf den zusammengesetzten Primärschlüssel (UserPK.java), wobei einer davon automatisch generiert wird (Feld mit der Bezeichnung id) und der zweite (Feldname Typ) wird am Anfang festgelegt.Frühling CrudRepository nicht id in zusammengesetzten Primärschlüssel

Und bekomme ich Fehler, wenn ich neues Objekt erstellen, mit der Verwendung von CRUDRepository (UserRepository.java) - nicht neues Objekt in der zweite Modell einfügen (UserInfo.java), weil id null (erstes Modell ist wurde korrekt hinzugefügt). Ich denke, das Problem liegt darin, den zusammengesetzten Primärschlüssel im Datenbankmodell zu teilen/abzubilden. Ich versuchte das gleiche Modell mit EntityManager und es war kein Fehler - alles wurde hinzugefügt. Ich benutzen Next @PrimaryKeyJoinColumns Anmerkung, aber mit dem gleichen Ergebnis wie oben (aber ich bin mir nicht sicher, dass ich es richtig verwendet wird) - CRUDRepository gescheitert und EntityManager Erfolg.

Kann mir jemand helfen, eine Lösung zu finden? Ich füge auch Quellcode auf GitHub hinzu, wenn jemand Code ausführen möchte.

Logs unter:

Log CRUDRepository

Hibernate: select user0_.id as id1_0_1_, user0_.type as type2_0_1_, user0_.email as email3_0_1_, user0_.login as login4_0_1_, userinfo1_.id as id3_1_0_, userinfo1_.type as type4_1_0_, userinfo1_.name as name1_1_0_, userinfo1_.surname as surname2_1_0_ from user user0_ left outer join user_info userinfo1_ on user0_.id=userinfo1_.id and user0_.type=userinfo1_.type where user0_.id=? and user0_.type=? 
Hibernate: call next value for seq_id 
Hibernate: select userinfo0_.id as id3_1_0_, userinfo0_.type as type4_1_0_, userinfo0_.name as name1_1_0_, userinfo0_.surname as surname2_1_0_ from user_info userinfo0_ where userinfo0_.id=? and userinfo0_.type=? 
Hibernate: insert into user (email, login, id, type) values (?, ?, ?, ?) 
Hibernate: insert into user_info (name, surname, id, type) values (?, ?, ?, ?) 
WARN 17653 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 23502, SQLState: 23502 
ERROR 17653 --- [nio-8080-exec-3] o.h.engine.jdbc.spi.SqlExceptionHelper : NULL not allowed for column "ID"; SQL statement: 
insert into user_info (name, surname, id, type) values (?, ?, ?, ?) [23502-196] 
... 

Log EntityManager

Hibernate: call next value for seq_id 
Hibernate: insert into user (email, login, id, type) values (?, ?, ?, ?) 
Hibernate: insert into user_info (name, surname, id, type) values (?, ?, ?, ?) 

-Code unten:

Hauptmodell: User.java

import com.fasterxml.jackson.annotation.JsonManagedReference; 
import javax.persistence.*; 
import javax.validation.constraints.NotNull; 
import java.io.Serializable; 

@Entity 
@Table(name = "USER") 
@IdClass(UserPK.class) 
public class User implements Serializable { 

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "user") 
    @JsonManagedReference 
    private UserInfo info; 

    @Id 
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ID") 
    @SequenceGenerator(name = "SEQ_ID", sequenceName = "SEQ_ID", allocationSize = 1) 
    @NotNull 
    @Column(name = "ID") 
    private Long id; 
    @Id 
    @NotNull 
    @Column(name = "TYPE") 
    private String type; 
    @NotNull 
    @Column(name = "LOGIN") 
    private String login; 
    @NotNull 
    @Column(name = "EMAIL") 
    private String email; 
    /* ... */ 
} 

Zweites Modell: UserInfo.java

import com.fasterxml.jackson.annotation.JsonBackReference; 
import javax.persistence.*; 
import java.io.Serializable; 

@Entity 
@Table(name = "USER_INFO") 
public class UserInfo implements Serializable { 

    @Id 
    @OneToOne(cascade = CascadeType.ALL) 
    @JoinColumns({ 
    @JoinColumn(name = "id", referencedColumnName = "id"), 
    @JoinColumn(name = "type", referencedColumnName = "type") 
    }) 
    @JsonBackReference 
    @MapsId 
    private User user; 

    @Column(name = "NAME") 
    private String name; 
    @Column(name = "SURNAME") 
    private String surname; 
    /* ... */ 
} 

Komponiert Primärschlüssel: UserPK.java

import java.io.Serializable; 

public class UserPK implements Serializable { 
    private Long id; 
    private String type; 
    /* ... */ 
} 

Feder CRUDRepository: UserRepository.java

import org.springframework.data.repository.CrudRepository; 
import org.springframework.stereotype.Repository; 

@Repository 
public interface UserRepository extends CrudRepository<User, UserPK> { 
    User findByIdAndAndType(Long id, String type); 
} 

Repository unter Verwendung EntityManager: UserRepositoryEM. java

import org.springframework.stereotype.Repository; 
import javax.persistence.EntityManager; 
import javax.persistence.PersistenceContext; 
import javax.transaction.Transactional; 

@Repository 
@Transactional 
public class UserRepositoryEM { 

    @PersistenceContext 
    private EntityManager entityManager; 

    public User findByKey(UserPK key) { 
     return entityManager.find(User.class, key); 
    } 

    public User save(User user) { 
     entityManager.persist(user); 
     entityManager.flush(); 
     return user; 
    } 
} 

Antwort

0

Die User und UserPK Klassen müssen leichte Modifikation. Ihre Spaltenzuordnungen für den Primärschlüssel sollten innerhalb der UserPK Klasse liegen. Hier sind die Änderungen,

@Entity 
@Table(name = "USER") 
public class User implements Serializable { 

    @OneToOne(cascade = CascadeType.ALL, mappedBy = "user") 
    @JsonManagedReference 
    private UserInfo info; 

    @EmbeddedId 
    private UserPK id; 

    @Column(name = "LOGIN", nullable = false) 
    private String login; 

    @Column(name = "EMAIL", nullable = false) 
    private String email; 
    /* ... */ 

    @Embeddable 
    @SequenceGenerator(name = "SEQ_ID", initialValue=1, allocationSize=100) 
    public static class UserPK implements Serializable { 

     @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "SEQ_ID") 
     @Column(name = "ID", nullable = false) 
     private Long id; 

     @Column(name = "TYPE", nullable = false) 
     private String type; 
    } 
} 

Entsprechende Änderungen in das Repository,

@Repository 
public interface UserRepository extends CrudRepository<User, User.UserPK> { 
    User findByIdAndAndType(Long id, String type); 
} 
+0

Dank für die Antwort, die ich ändern Code, wie Sie sagen: ** UserPK.java ** ** ** User.java + ** UserRepository.java **. Sie können Änderungen an [GitHub] (https://github.com/kaczla/SpringBootCompositePrimaryKey/tree/embeddedid) anzeigen. Jetzt ist es ein anderes Problem, kann Schlüssel nicht erzeugen - sogar ich setze Schlüssel, es kann nicht geteilt werden zu ** UserInfo.java ** – kaczla

+0

machte etwas Änderung zu UserPK Klasse wrt Folgegenerator. Probieren Sie es jetzt. –

+0

Ich habe ** UserPK.java ** geändert, aber es hat nicht geholfen. Beim Betrachten von Protokollen hat Hibernate keinen Sequenzer für ** UserPK.java ** erstellt, sodass die automatisch generierte ID nicht mit @Embeddable-Annotation erstellt werden kann oder etwas falsch gemacht wird. Auf der anderen Seite löse ich das Problem mit dem Sharing/Mapping Composite Primärschlüssel - ich habe nur * @ EmbeddedId * Annotation in ** UserInfo.java ** hinzugefügt. Natürlich können Sie Änderungen in [GitHub] sehen (https://github.com/kaczla/SpringBootCompositePrimaryKey/tree/embeddedid) – kaczla

Verwandte Themen