EBean est de ne pas faire de mises à jour! il essaie de faire des insertions et à défaut d'
j'ai un simple modèle d'Utilisateur comme ceci:
package models;
import java.util.*;
import javax.persistence.*;
import play.db.ebean.*;
@Entity
public class User extends Model {
@Id
public Long id;
public String userName;
public String email;
public String workPlace;
public Date birthDate;
@Version
public Long version;
public static Finder<Long,User> find = new Finder<Long,User>(
Long.class, User.class
);
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getWorkPlace() {
return workPlace;
}
public void setWorkPlace(String workPlace) {
this.workPlace = workPlace;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
public Long getVersion() {
return version;
}
public void setVersion(Long version) {
this.version = version;
}
}
dans MySql il y a déjà un dossier avec l'id=1, version=1
- je créer un nouveau modèle avec le même id+version, changer le nom d'utilisateur
puis j'ai essayer la méthode save ()
il échoue avec:
javax.persistence.PersistenceException: ERROR executing DML bindLog[] error[Duplicate entry '1' for key 'PRIMARY']
at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.execute(DmlBeanPersister.java:116) ~[ebean.jar:na]
at com.avaje.ebeaninternal.server.persist.dml.DmlBeanPersister.insert(DmlBeanPersister.java:76) ~[ebean.jar:na]
at com.avaje.ebeaninternal.server.persist.DefaultPersistExecute.executeInsertBean(DefaultPersistExecute.java:91) ~[ebean.jar:na]
at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeNow(PersistRequestBean.java:527) ~[ebean.jar:na]
at com.avaje.ebeaninternal.server.core.PersistRequestBean.executeOrQueue(PersistRequestBean.java:557) ~[ebean.jar:na]
at com.avaje.ebeaninternal.server.persist.DefaultPersister.insert(DefaultPersister.java:404) ~[ebean.jar:na]
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'PRIMARY'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) [na:1.7.0_05]
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) [na:1.7.0_05]
at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) [na:1.7.0_05]
at java.lang.reflect.Constructor.newInstance(Unknown Source) [na:1.7.0_05]
at com.mysql.jdbc.Util.handleNewInstance(Util.java:411) ~[mysql-connector-java-5.1.18.jar:na]
at com.mysql.jdbc.Util.getInstance(Util.java:386) ~[mysql-connector-java-5.1.18.jar:na]
ce que je fais mal?
insertion d'un nouvel enregistrement fonctionne. donc, il me semble que certains ebean d'un bug où les de son ne pas reconnaître qu'il convient de faire une mise à jour. ou est ce une config que j'ai oublié quelque part?
grâce
S'il vous plaît montrer le code où vous appelez la
pourquoi n'appelez-vous pas
save()
méthode.pourquoi n'appelez-vous pas
update()
OriginalL'auteur Or Gal | 2012-07-28
Vous devez vous connecter pour publier un commentaire.
Je pense que c'est lié à la bytecode amélioration à la fois de jouer et de ebean effectue.
J'ai eu des problèmes bizarres similaire à la vôtre lorsque j'ai mélangé des champs publics avec des getters et setters. Parfois, les valeurs n'étaient pas définis lors de l'utilisation du domaine directement:
C'était comme une potentielle mort de piège, alors j'ai décidé d'être cohérent et d'utiliser uniquement les champs publics. L'inconvénient était que ebeans d'auto-extraction a cessé de travailler, mais d'un autre côté, qui m'a contraint à tune de mes requêtes avec ebean extrait.
Cet excellent post par Timo jeter une certaine lumière sur la façon dont ebean et jouer effectue leur code binaire de la magie.
J'ai juste eu un très semblable question, assez étrange comportement. C'est la raison pour laquelle j'aime les Ressorts JdbcTemplate ses tous dehors dans l'ouvert. Vraiment aidé
Joel S, ta solution a fonctionné pour moi.
Merci beaucoup! Cette solution a fonctionné pour moi aussi!
OriginalL'auteur Joel S
Si vous avez une auto-créé objet et l'appel de save(), puis Ebean fait une instruction insert SQL. Si vous appelez mise à jour() il fera une mise à jour de l'énoncé SQL.
Il n'y a pas de logique dans le Ebean lui-même une requête supplémentaire pour DB juste pour vérifier, si il arrive à être une ligne similaire de la clé primaire dans la base de données, et si oui, utiliser une instruction de mise à jour sinon une instruction insert. Ce serait tout simplement être inefficace comportement de sa part, comme d'habitude, vous saurez à qui on à faire et donc ne veulent pas exécuter deux instructions SQL, juste un. Dans ce cas, vous avez réellement dire à utiliser une mise à jour, de ne pas essayer d'insérer une ligne de nouveau.
Toutefois, si vous allez chercher l'objet à partir de DB, puis de l'appel d' save (), il utilisera une instruction update en SQL, depuis Ebean sait que son état n'est pas nouvelle, plutôt que dans l'existant.
Voir Ebean documentation.
.save()
était incompatible (par exemple. une fois .save() de mettre à JOUR, la prochaine il va tenter d'INSÉRER), mais peut-être que j'étais juste manuellement la suppression de données sans s'en rendre compte. De toute façon, cette solution fonctionne très bien! Dans mon cas, j'ai pu tout tester pour voir si l'élément a uneid
bien ensemble, et si elle le fait, je sais qu'il pré-existe, donc, je peux appeler.update()
, sinon j'appelle.save()
. Cela me permet d'économiser un DB d'appel.Hmmm. Des questions comme celles-EBean horrible à utiliser avec Scala/Jouer.
Si vous préférez Ebean n'supplémentaire des requêtes SQL pour savoir si elle doit s'insérer ou mettre à jour sur un
save()
? Ce serait juste de la mauvaise performance.ce n'est pas ce que je voulais dire. Ce que je suis en train de réaliser que c'est assez simple unidirectionnel –
@OneToOne
avec Ebean échoue car en cascade essaie de l'insérer de nouveau le même ID sur la ligne enfant et les résultats dans une exception SQL. J'ai perdu une journée complète.Qui ne demande que la question de savoir pourquoi l'utilisation en cascade, en premier lieu, mais les commentaires ne sont pas vraiment la place pour une longue discussion qui est hors-sujet pour cette question.
OriginalL'auteur t0mppa