Violation de contrainte d'intégrité
En utilisant le Jeu! Cadre, j'ai le texte suivant deux modèles:
@Entity
public class User extends Model {
public String firstName;
public String lastName;
public String email;
public String password;
public boolean isAdmin;
@OneToMany(mappedBy="id", cascade=CascadeType.ALL)
public List<Site> sites;
public User(String firstName, String lastName, String email, String password) {
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
}
public static User connect(String email, String password) {
return User.find("byEmailAndPassword",email,Crypto.passwordHash(password)).first();
}
public static User findUser(String email) {
return User.find("byEmail",email).first();
}
public static User createUser(String firstName, String lastName, String email, String password, boolean isAdmin) {
String pw = Crypto.passwordHash(password);
User u = new User(firstName, lastName, email, pw);
u.isAdmin = isAdmin;
u.save();
return u;
}
}
@Entity
public class Site extends Model {
public UUID siteId;
public String alias;
public String protocol;
public String host;
public String username;
public String password;
public int port;
public String rootPath;
@Lob
public String description;
@ManyToOne
public User user;
public Site(User user, String alias, String protocol, String host, String username, String password) {
this.user = user;
this.alias = alias;
this.protocol = protocol;
this.host = host;
this.username = username;
this.password = password;
this.port = 21;
this.siteId = UUID.randomUUID();
}
}
Lorsque j'essaie d'exécuter le test suivant:
public class BasicTest extends UnitTest {
@Before
public void setup() {
Fixtures.deleteAll();
}
@Test
public void createAndRetrieveUser() {
new User("Jason","Miesionczek","something","something").save();
User jason = User.find("byEmail", "something").first();
assertNotNull(jason);
assertEquals("Jason", jason.firstName);
}
@Test
public void userSite() {
new User("Jason","Miesionczek","something","something").save();
User jason = User.find("byEmail", "something").first();
new Site(jason, "InterEditor","ftp","something","something","something").save();
List<Site> sites = Site.find("byUser", jason).fetch();
assertEquals(1, sites.size());
Site site1 = sites.get(0);
assertNotNull(site1);
assertEquals("InterEditor", site1.alias);
assertNotNull(site1.siteId);
}
}
Et j'obtiens cette erreur:
A javax.persistence.PersistenceException has been caught, org.hibernate.exception.ConstraintViolationException: could not insert: [models.Site]
In /test/BasicTest.java, line 27 :
new Site(jason, "InterEditor","ftp","something","something","something").save();
Journal de sortie:
00:06:26,184 WARN ~ SQL Error: -177, SQLState: 23000
00:06:26,184 ERROR ~ Integrity constraint violation - no parent FK2753674FD92E0A
table: USER in statement [insert into Site (id, alias, description, host, passw
ord, port, protocol, rootPath, siteId, user_id, username) values (null, ?, ?, ?,
?, ?, ?, ?, ?, ?, ?)]
Quelqu'un peut-il m'aider à comprendre ce que l'erreur de moyens et de ce que je fais de mal?
Je ne suis pas sûr si c'est la cause de votre problème, mais Hibernate exige que "Toutes les classes persistantes doit avoir un constructeur par défaut" (plus precice, aucun argument constructeur). Je n'ai pas le voir pour le Site et l'Utilisateur.
OriginalL'auteur Jason Miesionczek | 2010-12-12
Vous devez vous connecter pour publier un commentaire.
Votre problème ici, c'est la correspondance entre le Site de la classe du modèle et le modèle de l'Utilisateur de la classe. L'erreur donnée est un manque de clé étrangère.
Si vous commentez la liste de Site dans votre classe d'Utilisateur, de votre test passe. Alors, qui a réduit le problème.
Mise à jour:
Le problème est que lorsque votre Site objet est enregistré, il vous fera économiser de l'enfant des objets de première (qui comprend l'Utilisateur de l'objet). Lorsque cela se produit, c'est d'essayer de créer une référence à l'objet du Site (en raison de la mappedBy paramètre), mais cela n'a pas encore été enregistrée (ce sera fait APRÈS l'objet Utilisateur est enregistré).
Donc, une alternative serait à la carte par une valeur que vous avez accès à (tels que le siteId), ou ajouter l'Utilisateur au Site après qu'il a été enregistré (donc la valeur de l'ID a été généré.
J'ai changé votre code
mappedBy="siteId"
et l'exécution des tests d'amende.J'ai essayé ta suggestion, et maintenant j'ai cette erreur:
09:17:54,710 ERREUR ~ Échoué: alter table Site ajouter index FK2753671A145791 ( siteId), ajouter la contrainte FK2753671A145791 clé étrangère (siteId) les références de l'Utilisateur (i d) 09:17:54,710 ERREUR ~ BLOB/TEXT colonne 'id site" utilisé dans la spécification de la clé sans clé, longueur
Cela ressemble à une erreur MySQL avec des touches de type texte. La réponse peut donc être ajouter le lien entre l'Utilisateur et le Site après le Site objet a été enregistré, de sorte que l'ID existe.
j'ai donc changé le siteId à une Chaîne, car quand j'ai essayé de sauver l'UUID de la db, il a montré jusqu'à une chaîne de symboles aléatoires et beaucoup plus longtemps que les 36 caractères d'un UUID. j'ai également supprimé de la liste de sites de l'utilisateur de la classe que je n'utilise même pas la liste de cet objet. tout semble aller pour le sauver maintenant correctement. merci pour votre aide.
OriginalL'auteur Codemwnci
J'ai résolu un problème à l'aide de "DIFFÉRÉS INITIALEMENT non urgent" dans Oracle, ce qui retarde la vérification jusqu'à la validation de l'ensemble de la transaction !
OriginalL'auteur Alaa Murad