Koble en enhet fra JPA / EJB3 utholdenhet sammenheng

stemmer
52

Hva ville være den enkleste måten å koble en bestemt JPA Entity Bean som ble ervervet gjennom en EntityManager. Alternativt kunne jeg har et spørsmål returfrittliggende stedene i første omgang, slik at de vil i hovedsak fungere som 'bare lese'?

Grunnen til at jeg ønsker å gjøre dette er fordi jeg ønsker å endre dataene i bønne - med i søknaden min bare, men aldri har det vedvarte til databasen. I mitt program, har jeg til slutt å ringe flush () på EntityManager, noe som ville vedvare alle endringer fra vedlagte enheter til underyling database, men jeg ønsker å ekskludere bestemte objekter.

Publisert på 28/08/2008 klokken 00:53
kilden bruker
På andre språk...                            


15 svar

stemmer
55

(Kan være for sent å svare, men kan være nyttig for andre)

Jeg utvikler min første system med JPA akkurat nå. Dessverre jeg møtt med dette problemet når dette systemet er nesten fullført.

For å si det enkelt. Bruk Hibernate, eller vente på JPA 2.0.

I Hibernate, kan du bruke 'session.evict (objekt)' for å fjerne et objekt fra sesjon. I JPA 2,0, i utkast akkurat nå , er det 'EntityManager.detach (objekt)' metode for å koble en gjenstand fra utholdenhet sammenheng.

Svarte 22/05/2009 kl. 14:04
kilden bruker

stemmer
25

Uansett hvilken JPA implementering du bruker, bare bruke entityManager.detach(object)det nå i JPA 2.0 og en del av JEE6.

Svarte 27/08/2012 kl. 10:04
kilden bruker

stemmer
19

Hvis du trenger å koble et objekt fra EntityManager og du bruker Hibernate som underliggende ORM laget du kan få tilgang til Hibernate Session objektet og bruke Session.evict (Object) metode som Mauricio Kanada nevnt ovenfor.

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

Selvfølgelig dette ville bryte hvis du byttet til en annen ORM leverandør, men jeg tror dette er fortrinnsvis til å prøve å lage en dyp kopi.

Svarte 12/01/2010 kl. 14:10
kilden bruker

stemmer
18

Dessverre er det ikke mulig å koble ett objekt fra foretaket manager i dagens JPA gjennomføring, skjønne.

EntityManager.clear () vil koble alle de JPA objekter, slik at ikke kan være en hensiktsmessig løsning i alle tilfeller, hvis du har andre objekter du har tenkt å holde kontakten.

Så det beste alternativet ville være å klone objektene og bestå kloner til koden som endrer objektene. Siden primitive og uforanderlige objektfelt blir tatt hånd om av standard kloning mekanismen på en skikkelig måte, vil du ikke å skrive mye av VVS-kode (bortsett fra dypt kloning noen aggregerte strukturer du måtte ha).

Svarte 28/08/2008 kl. 18:39
kilden bruker

stemmer
3

Hvis du bruker EclipseLinkhar du også muligheter,

Bruk Query hint, eclipselink.maintain-cache"="false- alle returnerte objekter vil bli frittliggende.

Bruk EclipseLink JpaEntityManager copy()API for å kopiere objektet til den ønskede dybde.

Svarte 31/03/2011 kl. 13:16
kilden bruker

stemmer
3

Så vidt jeg vet, den eneste direkte måter å gjøre det er:

  1. Forplikte txn - Sannsynligvis ikke et rimelig alternativ
  2. Tømme Persistence Kontekst - EntityManager.clear () - Dette er brutal, men vil tømme den ut
  3. Kopier objekt - Mesteparten av tiden din JPA objekter er serial, så dette bør være lett (hvis ikke spesielt effektivt).
Svarte 28/08/2008 kl. 01:45
kilden bruker

stemmer
1

Må forholde seg til en lignende sak jeg har laget en DTO objekt som utvider vedvarende foretaket objektet som følger:

class MyEntity
{
   public static class MyEntityDO extends MyEntity {}

}

Til slutt vil en skalar spørring hente de ønskede ikke klarte attributter:

(Hibernate) select p.id, p.name from MyEntity P
(JPA)       select new MyEntity(p.id, p.name) from myEntity P
Svarte 03/09/2014 kl. 16:16
kilden bruker

stemmer
1

I JPA 1.0 (testet med EclipseLink) kan du hente foretaket utsiden av en transaksjon. For eksempel, med container klarte transaksjoner du kan gjøre:

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);
}
Svarte 04/06/2013 kl. 22:03
kilden bruker

stemmer
1

Siden jeg bruker SØM og JPA 1.0 og mitt system har en fuctinality som trenger å logge alle felt endringer, har jeg opprettet en verdi objekt eller dataoverføring objekt hvis samme feltene i foretaket som må være logget inn. Konstruktøren av den nye POJO er:

    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();
            }
        }
    }
}
Svarte 30/03/2011 kl. 20:12
kilden bruker

stemmer
1

dette er rask og skitne, men du kan også serial og deserialize objektet.

Svarte 22/10/2009 kl. 07:59
kilden bruker

stemmer
1

Mauricio Canada, takk til deg for råd, metode kaste ut () fungerer fint. Jeg bruker JPA fra SØM, det er innebygd støtte for JPA Entity Behandling, og det er mulig å få tilgang til dvale delegat Session og dermed denne metoden "kaste ut".

Mange takk, Zmicer

Svarte 29/07/2009 kl. 16:36
kilden bruker

stemmer
1

Hvis det ikke er for mange eiendommer i bønne, kan du bare lage en ny forekomst og sette alle sine eiendommer manuelt fra vedvarte bønne.

Dette kan gjennomføres som en kopi konstruktør, for eksempel:

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

Deretter:

Thing newBean = new Thing(oldBean);
Svarte 28/08/2008 kl. 02:36
kilden bruker

stemmer
0

Jeg tror det er en måte å kaste ut en enkelt enhet fra EntityManager ved å kalle dette

EntityManagerFactory emf;
emf.getCache().evict(Entity);

Dette vil fjerne bestemt enhet fra cache.

Svarte 25/10/2018 kl. 18:39
kilden bruker

stemmer
0

Hvis du får her fordi du faktisk ønsker å passere en enhet på tvers av en ekstern grense så du bare sette noen kode i å lure hibernazi.

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

Cloneable wont arbeide fordi det faktisk kopierer PersistantBag over.

Og glem om bruk Serializable og bytearray bekker og rør bekker. å lage tråder for å unngå vranglåser dreper hele konseptet.

Svarte 27/05/2011 kl. 08:57
kilden bruker

stemmer
-1

Jeg tror du kan også bruke metoden EntityManager.refresh (Object o) hvis primærnøkkelen av foretaket ikke har blitt endret. Denne metoden vil gjenopprette opprinnelige tilstand av foretaket.

Svarte 27/11/2009 kl. 12:21
kilden bruker

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