Как заставить TopLink немедленно установить отношение OneToMany? - PullRequest
0 голосов
/ 06 декабря 2010

У меня есть два энтита, Person и Teacher, с отношением OneToMany:

public class Person implements Serializable {
    @Id
    @Column(nullable = false)
    private String login;
    @OneToMany(mappedBy = "person")
    private List<Teacher> teacherList;
}

public class Teacher implements Serializable {
    @ManyToOne
    @JoinColumn(name = "LOGIN")
    private Person person;
}

У меня также есть класс DTO для Person:

public class PersonDTO extends Person {
    private boolean isTeacher;

    public PersonDTO(Person p) {
        setLogin(p.getLogin());
        isTeacher = getTeacherList().size() > 0;
    }

    public boolean isTeacher() {
        return isTeacher;
    }
}

Мой EJB имеет такой код для вставки новых Teacher с и чтения Person с:

public void addTeacher(String login, String password, String name,
                       String dept, String title) {
    p = new Person(true, false, login, name, password);
    persistEntity(p);
    Teacher t = new Teacher(dept, p, title);
    persistEntity(t);
    em.flush();    // 'em' is the Entity Manager
}

public PersonDTO readPerson(String login) {
    Person p = em.find(Person.class, login);
    PersonDTO pdto = new PersonDTO(p);
    return pdto;
}

На моей веб-странице есть таблица, показывающая всех учителей, текстовые поля для различных полей и кнопка для добавления нового учителя и обновления таблицы, слушатель для которой выглядит следующим образом:

public void addTeacherListener(ActionEvent actionEvent) {
    adminManager.addTeacher(/* parameters */);

    // update table (which is bound to 'teacherList')
    teacherList = new LinkedList<Teacher>();
    List<String> logins = adminManager.findAllPerson();
    for (String login : logins) {
        PersonDTO pdto = adminManager.readPerson(login);
        if (pdto.isTeacher()) {
          teacherList.add(pdto.getTeacherList().get(0));
        }
    }
}

Проблема в том, что после вставки нового Учителя он не отображается в таблице. Точная причина этого заключается в том, что для объекта PersonDTO, возвращаемого readPerson, isTeacher имеет значение false: это означает, что во время создания объекта DTO (то есть после завершения операции вставки, в том числе две персистентные и сброс в конце), объект Person для данного учителя имеет пустой teacherList.

Однако, если я закрою страницу и перезапущу ее из IDE, вновь вставленные элементы отобразятся в таблице. Так что, очевидно, TopLink устанавливает отношения, но не сразу. Что именно происходит, и как я могу заставить его сделать это сразу после вставки?

1 Ответ

1 голос
/ 06 декабря 2010

JPA не поддерживает согласованные двунаправленные отношения между объектами в памяти автоматически, это ваша собственная задача.

То есть после выполнения addTeacher() у вас есть свойство Teacher с person, указывающее на Person.Это отношение отражено в базе данных, но не отражено в teacherList из Person, который уже находится в памяти.em.find() возвращает существующий экземпляр Person из контекста постоянства, поэтому его teacherList является пустым.

Поэтому вам нужно добавить Teacher в Person.teacherList в addTeacher().

...