2014-12-28 11 views
7

Hallo, ich bin neu in Sprig Daten JPA Einfügen und ich frage mich, obwohl ich die Id an das Unternehmen übergeben, die Frühjahrsdaten JPA wird das Einfügen statt verschmelzen. Ich dachte, wenn ich die Persistable-Schnittstelle implementieren und die beiden Methoden implementieren:Spring Data JPA statt aktualisieren

public Long getId(); 
public Boolean isNew(); 

Es wird automatisch fusionieren statt bestehen bleiben.

Ich habe eine Entity-Klasse namens Benutzer wie:

@Entity 
@Table(name = "T_USER") 
public class User implements Serializable, Persistable<Long> { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    @Column(name = "USER_ID") 
    private Long id; 

    @Column(name = "CREATION_TIME", nullable = false) 
    private Date creationTime; 

    @Column(name = "FIRST_NAME", nullable = false) 
    private String firstName; 

    @Column(name = "LAST_NAME", nullable = false) 
    private String lastName; 

    @Column(name = "MODIFICATION_TIME", nullable = false) 
    private Date modificationTime; 

Und haben eine andere Klasse

@Entity 
@Table(name = "T_USER_ROLE") 
public class UserRole implements Serializable, Persistable<Long> { 

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long roleId; 

    @Column(name = "ROLE_NAME") 
    private String userRole; 
} 

ich eine benutzerdefinierte Repository UserRepostory erstreckt JpaReopistory genannt. Ich treffe das Speichern für die Zusammenführung und behalte es bei, während ich sehe, dass die Implementierung zeigt, dass Spring Data Jpa über zwei Methoden entweder zum Aktualisieren oder Einfügen verwendet.

@Repository 
public interface UserRepository extends JpaRepository<User, Long> { 
} 

Ich habe versucht, herauszufinden, aber keine Ahnung bekommen. Vielleicht können Sie Jungs helfen.

+0

Sie müssen die persistable-Schnittstelle nicht implementieren. Verwenden Sie einfach das geerbte 'save' und Spring Data wird es für Sie übernehmen. –

Antwort

20

Ich lief in dieses Problem, versuchte Persistable ohne Erfolg zu implementieren, und dann in die Spring Data JPA-Quelle geschaut. Ich sehe das nicht unbedingt in Ihrem Beispielcode, aber ich habe ein @Version Feld in meiner Entität. Wenn ein Feld @Version vorhanden ist, wird Spring Data den Wert testen, um festzustellen, ob die Entität neu ist oder nicht. Wenn das Feld @Version kein primitives Element ist und null ist, wird die Entität als neu betrachtet.

Dies warf mich für eine lange Zeit in meinen Tests, weil ich nicht das Feld Version in meiner Darstellung, sondern nur auf der persistenten Entität festgelegt wurde. Ich sehe das auch nicht in den ansonsten hilfreichen Spring Data Dokumenten (was ein anderes Thema ist ...).

Hoffnung, dass jemand hilft!

+0

Ja, du hast Recht.Ich hatte das Feld Version in der Entität. Ich wusste nie, dass Spring Data JPA nach diesem Feld suchen würde. –

+0

Ich habe genau das gleiche Problem und ist nicht für @Version Anmerkungen ... – multiplayer1080

+0

Dank für diese Antwort stieß ich auf das gleiche Problem! – JamesG

2

Standardmäßig überprüft Spring Data JPA die Bezeichnereigenschaft der angegebenen Entität. Wenn die Bezeichnereigenschaft null ist, wird die Entität als neu angenommen, andernfalls als nicht neu. Es ist Id-Property inspectionReference

Wenn Sie Frühlings-JPA verwenden mit EntityManeger.merge() Aufruf wird Ihre entuty aktualisieren und .persist() wird einfügen.

@PersistenceContext 
private EntityManager em; 

@Override 
@Transactional 
public User save(User user) { 

    if (user.getId() == null) { 
     em.persist(user); 
     return user; 
    } else { 
     return em.merge(user); 
    } 
} 

Die Schnittstelle Persistable muss nicht implementiert werden.

+0

Vielen Dank @njjnex. Wenn Sie jedoch die JpaRepository-Schnittstelle verwenden und die Save-Methode von der Service-Klasse aufrufen, sehen Sie, dass Spring Data JPA intern prüft, ob die Entität neu ist oder nicht. Wenn eine Entität die Persistable-Schnittstelle von Spring implementiert, überschreibt sie auf diese Weise zwei Methoden: 1. Boolean isNew() und 2. Long getId(). Aber es funktioniert nicht. –

+2

Wie gesagt, ich komme in Spring Data Jpa und habe vorher eigene Dao-Layer verwendet. Ich habe den oben erwähnten Weg gemacht, indem ich den EntityManager in der Dao-Implementierung übergeben habe. Das funktioniert gut, aber meine Frage ist, warum es nicht im Zusammenhang mit Spring Daten Jpa funktioniert. –