обновить спящий JPA - PullRequest
       1

обновить спящий JPA

0 голосов
/ 11 июня 2011

В спящем JPA, как я могу обновить объект? У меня есть один объект проекта, имеющий два атрибута. Проект и название проекта. Здесь проект является первичным ключом. Теперь в моем методе обновления я должен иметь возможность изменять как атрибуты проекта, так и имя проекта. Запрос должен выглядеть следующим образом.

update PROJECT set ID='123',NAME='Intel' where ID='122'

Я хочу присвоить идентификатор_проекта идентификатору_пользователя.

project_table
-------------
project_id  project_name  
-------------------------  
LK987       LockSystem  
MK876       MockSystem      


user_project_table
---------------------  
user_id        project_id  
--------------------------  
12343       LK987  
12344       MK876  
12343       TK656  
12675       TK656  

Ответы [ 2 ]

2 голосов
/ 11 июня 2011

Если идентификатор проекта является первичным ключом и идентификатором объекта, вы никогда не должны изменять его. Изменение первичного ключа означает, что представленный объект изменяется на что-то совершенно другое.

JPA предполагает, что первичный ключ является фиксированным. Операции чтения, обновления и удаления идентифицируют рассматриваемый объект по его идентификатору. Если вы измените идентификатор объекта и выполните обновление, JPA либо обновит какой-то совершенно другой объект (что может привести к исключению), либо не найдет объект для обновления вообще.

Чтобы подчеркнуть это, спецификация JPA запрещает изменение первичного ключа. Hibernate также может исключать первичный ключ из любого сгенерированного оператора обновления. См. Стр. 28 из JSR-317

Значение его первичного ключа однозначно идентифицирует экземпляр объекта в постоянный контекст и Операции EntityManager как описано в главе 3 «Операции с субъектами». приложение не должно изменять значение первичного ключа (это включает в себя не изменение значения изменяемого типа, который является первичным ключом или атрибутом составного первичного ключа). Поведение не определено, если это происходит (реализация может, но не обязана, генерировать исключение. Переносимые приложения не должны полагаться на такое поведение).

Чтобы достичь желаемого результата, вы должны удалить старый объект и создать новый.

2 голосов
/ 11 июня 2011

Перестаньте думать на SQL, начните думать на EntityManager. Проект p = entityManager.find (Project.class, 122); p.setId (123); p.setName ( "Intel"); entityManager.merge (р);

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

Зачем вам менять личность сущности? Вам также необходимо обновить все внешние ключи в других таблицах, которые на него указывают. Похоже на боль, без выгоды. Возможно, вам лучше сделать это «бизнес-ключом» (обычное свойство) и использовать более постоянный суррогатный ключ.

Если вы действительно должны иметь возможность изменить идентификационный номер проекта, вы должны изменить первичный ключ на автоматически инкрементный номер. Сущность будет выглядеть примерно так:

@Entity
public class Project
{
    @Id @GeneratedValue
    private int id;
    private int projectId;
    private String projectName;

    // getters and setters
}


Итак, вы хотите связать проекты с пользователями.

Вы можете сделать это, если идентификатор проекта (строка, например, "LK987") является первичным ключом (который, я уверен, теперь вы понимаете, что изменять его не следует) & mdash; или вы можете использовать отдельный автоинкремент int в качестве идентификатора. Тебе решать; Мое личное предпочтение - подход автоинкремента, так что вам не нужно беспокоиться об этом позже.

То, что вы пытаетесь сделать, это установить отношения между Project сущностями и User сущностями. Вместо хранения полей внешнего ключа следует хранить поля entity (для сопоставлений один-к-одному, один-ко-многим или многие-к-одному) или наборы сущностей (для сопоставлений один-ко-многим) сопоставления «многие к одному» или «многие ко многим»). Если я понимаю, что вам нужно:

  • У каждого пользователя может быть несколько проектов, и у каждого проекта может быть несколько пользователей (так что сопоставление много-ко-многим)
  • Пользователи знают о проектах, и проекты могут также знать о пользователях (поэтому отображение является двунаправленным). Я предполагаю, что User является владельцем отношений, а Project является обратной стороной.

Это означает, что вы будете использовать аннотацию @ManyToMany и указать @JoinTable и какие @JoinColumn s использовать.

Класс сущности пользователя

@Entity
public class User
{
    @Id @GeneratedValue
    int id;  // the PK for user entities

    @ManyToMany
    @JoinTable(
        name="user_project_table",
        joinColumns=@JoinColumn(name="user_id"),
        inverseJoinColumns=@JoinColumn(name="project_id"))
    Set<Project> projects;

    // snip...
}

Класс сущности проекта

@Entity
public class Project
{
    @Id @GeneratedValue
    int id;
    String projectId;
    String projectName;

    @ManyToMany(mappedBy="projects")
    Set<User> users;

    // snip...
}

Обратите внимание, что мы используем полноценные классы сущностей, а не только внешние ключи.

Дальнейшее чтение из Учебное пособие по Java EE 6 :

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