Отделить объект от / EJB3 контекста инерционности JPA

голоса
52

Что бы самый простой способ отделить конкретный JPA Entity Bean, который был приобретен через EntityManager. С другой стороны, я мог иметь возвращаемые запрос отдельных объектов, в первую очередь, чтобы они были по существу действуют как «только для чтения»?

Причина, почему я хочу сделать это потому что я хочу, чтобы изменить данные в компоненте - в моем приложении только, но не когда-либо она сохраняется в базу данных. В моей программе, я в конце концов придется вызывать Flush () на EntityManager, которая будет сохраняться все изменения от присоединенных организаций к базе данных underyling, но я хочу, чтобы исключить определенные объекты.

Задан 28/08/2008 в 01:53
источник пользователем
На других языках...                            


14 ответов

голоса
54

(Может быть слишком поздно, чтобы ответить, но могут быть полезны для других)

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

Проще говоря. Использование Hibernate, или ждать JPA 2.0.

В Hibernate, вы можете использовать «session.evict (объект)» , чтобы удалить один объект из сессии. В JPA 2.0, в проекте прямо сейчас , есть «EntityManager.detach (объект)» метод , чтобы отделить один объект от контекста инерционности.

Ответил 22/05/2009 d 15:04
источник пользователем

голоса
24

Независимо от того , который JPA реализации вы используете, просто не использовать entityManager.detach(object)его в настоящее время в JPA 2.0 и часть JEE6.

Ответил 27/08/2012 d 11:04
источник пользователем

голоса
19

Если вам нужно отделить объект от EntityManager и вы используете Hibernate в качестве основного ОРМ слоя вы можете получить доступ к Hibernate Session объекта и использовать Session.evict (Object) метод , который Маурисио Kanada упоминалось выше.

public void detach(Object entity) {
    org.hibernate.Session session = (Session) entityManager.getDelegate();
    session.evict(entity);
}

Конечно, этот перерыв будет, если вы перешли к другому провайдеру ORM, но я думаю, что это предпочтительно, чтобы пытаться сделать глубокую копию.

Ответил 12/01/2010 d 15:10
источник пользователем

голоса
18

К сожалению, нет никакого способа, чтобы отключить один объект от управляющего объекта в текущей реализации JPA, Afair.

EntityManager.clear () отключит все объекты JPA, так что не может быть подходящим решением во всех случаях, если у вас есть другие объекты вы планируете поддерживать связь.

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

Ответил 28/08/2008 d 19:39
источник пользователем

голоса
3

При использовании у EclipseLinkвас также есть варианты,

Используйте подсказку запроса, eclipselink.maintain-cache"="false- все возвращенные объекты будут отключены.

Используйте EclipseLink JpaEntityManager copy()API , чтобы скопировать объект на нужную глубину.

Ответил 31/03/2011 d 14:16
источник пользователем

голоса
3

Насколько я знаю, только прямые способы сделать это, являются:

  1. Зафиксируйте TxN - Наверное, не разумный вариант
  2. Очистить контекст Persistence - EntityManager.clear () - это жестокая, но очистит его
  3. Скопируйте объект - Большую часть времени ваши объекты JPA сериализуемы, так что это должно быть легко (если не особенно эффективно).
Ответил 28/08/2008 d 02:45
источник пользователем

голоса
1

Как иметь дело с подобным случае я создал объект DTO, который расширяет постоянный объект сущности следующим образом:

class MyEntity
{
   public static class MyEntityDO extends MyEntity {}

}

Наконец, скалярная запрос будет извлекать нужные не управляемые атрибуты:

(Hibernate) select p.id, p.name from MyEntity P
(JPA)       select new MyEntity(p.id, p.name) from myEntity P
Ответил 03/09/2014 d 17:16
источник пользователем

голоса
1

В JPA 1.0 (проверено с помощью EclipseLink) вы можете получить объект за пределами сделки. Например, с контейнером транзакции, управляемые вы могли бы сделать:

public MyEntity myMethod(long id) {
    final MyEntity myEntity = retrieve(id);
    // myEntity is detached here
}

@TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
public MyEntity retrieve(long id) {
    return entityManager.find(MyEntity.class, id);
}
Ответил 04/06/2013 d 23:03
источник пользователем

голоса
1

Так как я использую шовный и JPA 1.0 и моя система имеет fuctinality, который должен регистрировать все поля изменений, я создал объект или значения передачи данных объект, если один и тот же поле объекта, который должен быть зарегистрировано. Конструктор нового POJO является:

    public DocumentoAntigoDTO(Documento documentoAtual) {
    Method[] metodosDocumento = Documento.class.getMethods();
    for(Method metodo:metodosDocumento){
        if(metodo.getName().contains("get")){
            try {
                Object resultadoInvoke = metodo.invoke(documentoAtual,null);
                Method[] metodosDocumentoAntigo = DocumentoAntigoDTO.class.getMethods();
                for(Method metodoAntigo : metodosDocumentoAntigo){
                    String metodSetName = "set" + metodo.getName().substring(3);
                    if(metodoAntigo.getName().equals(metodSetName)){
                        metodoAntigo.invoke(this, resultadoInvoke);
                    }
                }
            } catch (IllegalArgumentException e) {
                e.printStackTrace();
            } catch (IllegalAccessException e) {
                e.printStackTrace();
            } catch (InvocationTargetException e) {
                e.printStackTrace();
            }
        }
    }
}
Ответил 30/03/2011 d 21:12
источник пользователем

голоса
1

это быстрый и грязный, но вы также можете сериализации и десериализации объекта.

Ответил 22/10/2009 d 08:59
источник пользователем

голоса
1

Маурисио Kanada, спасибо Вам за этот совет, метод выселить () работает хорошо. Я использую JPA из SEAM, есть встроенный в поддержку JPA Entity менеджера, и можно получить доступ к гибернации делегата сессии и, таким образом, этот метод «выселить».

Большое спасибо, Zmicer

Ответил 29/07/2009 d 17:36
источник пользователем

голоса
1

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

Это может быть реализован в виде конструктора копии, например:

public Thing(Thing oldBean) {
  this.setPropertyOne(oldBean.getPropertyOne());
  // and so on
}

Затем:

Thing newBean = new Thing(oldBean);
Ответил 28/08/2008 d 03:36
источник пользователем

голоса
0

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

for(RssItem i : result.getChannel().getItem()){
}

Cloneable не будет работать, потому что он действительно копирует PersistantBag поперечника.

И забудьте об использовании сериализуемых и ByteArray, потоков и потоков конвейера. создания потоков, чтобы избежать тупиков убивает всю концепцию.

Ответил 27/05/2011 d 09:57
источник пользователем

голоса
-1

Я думаю, вы также можете использовать метод EntityManager.refresh (Object о), если первичный ключ сущности не был изменен. Этот метод будет восстановить исходное состояние объекта.

Ответил 27/11/2009 d 13:21
источник пользователем

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more