JPA не успя да запази записа с асоциацията на външен ключ ManyToOne

Каква е разликата между метода EntityManager.find() и персонализирана заявка за избор на това конкретно въвеждане на данни?

Имам обект Student, който има ограничение за външен ключ към обекта School чрез SCHOOL_ID. Когато поддържа нов запис на ученик, JPA се опитва да вмъкне съществуващ запис на училище в таблицата SCHOOL, което води до изключения за интегритета на DB. Училищният запис беше добавен към досието на ученика чрез код по-долу:

student.setSchool(em.createNamedQuery("getSchoolByName", School.class).setParameter("name", schoolName).getSingleResult());

Запитването е

@NamedQueries({@NamedQuery(name="getSchoolByName", query="SELECT sc FROM School sc WHERE ts.name = :name")})

Има уникално ограничение за полето за име на училище, следователно дадено име със сигурност ще даде един резултат.

Но ако използвам метода find(), за да извлека училищния запис чрез неговия идентификатор (първичен ключ), няма такъв проблем.

student.setSchool(em.find(School.class, schoolId)); 

Както STUDENT, така и таблицата SCHOOL приемат id като първичен ключ.

Асоциацията на външния ключ в класа на обекта Student изглежда така

//uni-directional many-to-one association to TestSuite
@ManyToOne(targetEntity=School.class,cascade={CascadeType.PERSIST, CascadeType.MERGE, CascadeType.REFRESH})
@JoinColumn(name="SCHOOL_ID", referencedColumnName="SCHOOL_ID", nullable=false, insertable=false, updatable=false)
private School school;

person Ruifeng Ma    schedule 08.12.2015    source източник


Отговори (1)


Оказа се, че това е проблем с контекста на постоянството. Заявката всъщност е направена от нов мениджър на обекти, който има различен контекст от мениджъра на обекти, който обработва запазването. Веднъж обединени в един мениджър на обекти, вече нямаше проблем. find() и персонализираната заявка дават същия резултат.

person Ruifeng Ma    schedule 08.12.2015