Нарушение целостности - PullRequest
4 голосов
/ 12 декабря 2010

Использование Play!Framework, у меня есть следующие две модели:

@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();

    }
}

Когда я пытаюсь запустить следующий тест:

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);
    }



}

И я получаю эту ошибку:

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();

Вывод журнала:

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, ?, ?, ?,
 ?, ?, ?, ?, ?, ?, ?)]

Может кто-нибудь помочь мне понять, что означает ошибка и что я делаю неправильно?

Ответы [ 2 ]

6 голосов
/ 12 декабря 2010

Ваша проблема здесь заключается в отображении между классом модели сайта и классом модели пользователя. Ошибка: отсутствует внешний ключ.

Если вы закомментируете список сайтов в вашем классе пользователя, ваш тест пройдет успешно. Так что это сузило проблему.

Обновление:

Проблема заключается в том, что при сохранении объекта Site он сначала сохраняет дочерние объекты (включая объект User). Когда это происходит, он пытается создать ссылку на объект Site (из-за параметра mappedBy), но он еще не был сохранен (это будет сделано ПОСЛЕ сохранения объекта User).

Таким образом, альтернативой может быть сопоставление по значению, к которому у вас есть доступ (например, siteId), или добавление пользователя на сайт после его сохранения (чтобы было сгенерировано значение идентификатора.

Я изменил ваш код на mappedBy="siteId", и тестовый запуск прошел нормально.

2 голосов
/ 06 января 2013

Я решил такую ​​проблему с помощью «ПЕРВОНАЧАЛЬНО ОТЛОЖЕННОГО ОТЛОЖЕНИЯ» в Oracle, это задерживает проверку до тех пор, пока вы не совершите всю транзакцию!

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...