обновить JPA в спящем режиме

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

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

Я хочу назначить project_id для user_id.

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  

person user414967    schedule 11.06.2011    source источник


Ответы (2)


Перестаньте думать на SQL, начните думать на EntityManager. Project p = entityManager.find(Project.class, 122); p.setId(123); p.setName("Интел"); сущностьМенеджер.слияние(р);

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

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

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

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

    // getters and setters
}


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

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

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

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

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

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

@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:

person Matt Ball    schedule 11.06.2011
comment
+1 за конец ответа. Начало немного сомнительное в данный момент. - person Aleksi Yrttiaho; 11.06.2011
comment
Привет, Мэтт. Спасибо за информацию. Я хочу присвоить идентификатор проекта идентификатору пользователя. Как присвоить идентификатор проекта идентификатору пользователя? Какой из них я должен назначить project_id или сгенерированный автоинкрементом идентификатор? Как создать обе таблицы? И, возможно, идентификатор проекта будет иметь тип String. Для меня я должен быть в состоянии изменить project_id наверняка, потому что, если пользователь может ввести неправильный project_id и если ему/ей нужно изменить project_code позже, это должно быть полезно в опции редактирования. - person user414967; 12.06.2011
comment
Когда вы говорите Я хочу присвоить идентификатор проекта идентификатору пользователя, вы имеете в виду, что хотите иметь возможность связывать проекты с пользователями? Что касается Какой из них я должен назначить, вы спрашиваете об изменении значения project_id или идентификатора автоинкремента? Никогда. Изменять. . Начальный. Ключ. - person Matt Ball; 12.06.2011
comment
Да, я хочу связать проекты с пользователями. Как в таком случае установить связь между пользователем и проектом? Если я хочу установить отношения, мне нужно определить project_id как PK. Таким образом, этот PK будет FK в таблице пользователей для определения того, сколько проектов связано с пользователем. Хотя мы говорим об обновлении идентификатора проекта, я полностью запутался в способе проектирования. Пожалуйста, дайте мне понять. Я понял, что ПК никогда не должен меняться. - person user414967; 12.06.2011
comment
Хорошо, я следую. Есть лучший способ, чем беспокоиться о внешних ключах. Помните первое предложение моего ответа? Это все еще применимо. В JPA вы можете/должны заменить поля, в которых хранятся внешние ключи, полями, в которых хранятся сущности (или коллекции сущностей). Я соответствующим образом редактирую свой ответ, но в основном вам нужно знать о @OneToOne и/или @OneToMany . Может ли каждый пользователь иметь только один проект или каждый пользователь может иметь несколько проектов? - person Matt Ball; 12.06.2011
comment
Может ли каждый проект иметь несколько пользователей? Это больше похоже на @ManyToMany. В любом случае вам, вероятно, следует создать отдельную таблицу соединений для связывания проектов и пользователей. - person Matt Ball; 12.06.2011
comment
Да, у каждого пользователя может быть несколько проектов, и у каждого проекта может быть несколько пользователей. И еще одна вещь, которую я хотел бы упомянуть здесь: когда пользователь создается, ни один из проектов не назначается. После того, как пользователь создан, есть одна страница для назначения пользователей в проект. Там только я назначаю Проекты пользователям. - person user414967; 12.06.2011
comment
Хорошо, я пропустил, что вы уже используете таблицу соединений (извините!). Я все еще редактирую свой ответ... - person Matt Ball; 12.06.2011
comment
Привет, Мэтт! Большое спасибо за ваши ценные усилия. Я почти разобрался с понятиями. Позвольте мне снова пройтись по кораблям отношений. Потом сделаю пост здесь. Большое спасибо еще раз. - person user414967; 12.06.2011

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

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

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

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

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

person Aleksi Yrttiaho    schedule 11.06.2011