Domanda

C'è molto si può trovare su questo googling un po 'ma non ho abbastanza trovato una soluzione praticabile a questo problema.

Fondamentalmente quello che ho è un grande CLOB su una particolare classe che voglio avere caricato su richiesta. Il modo ingenuo per fare questo potrebbe essere:

class MyType {

  // ...

  @Basic(fetch=FetchType.LAZY)
  @Lob
  public String getBlob() {
    return blob;
  }
}

che non funziona, però, a quanto pare a causa del fatto che sto utilizzando driver Oracle, oggetti cioè Lob non sono trattati come le maniglie semplici, ma vengono sempre caricati. O così mi è stato portato a credere dalle mie incursioni. C'è una soluzione che utilizza strumenti speciali per la proprietà caricamento pigro, ma come Hibernate documenti sembra suggerire che sono meno interessati a fare in modo corretto, che il lavoro, in modo da preferisco non seguire questa strada. Soprattutto con dover eseguire un passaggio di compilazione in più e tutti.

Quindi, la soluzione successiva che avevo immaginato stava separando questo oggetto ad un altro tipo e la definizione di un'associazione. Purtroppo, mentre la documentazione give informazioni contrastanti, è evidente per me che lazy loading non funziona su associazioni OnetoOne con chiave primaria condivisa. Avevo impostato un lato dell'associazione come ManyToOne, ma io non sono molto sicuro come fare questo quando c'è una chiave primaria condivisa.

Qualcuno può suggerire il modo migliore per andare su questo?

È stato utile?

Soluzione

questo solo PostgreSQL implementa Blob come veramente pigri. Quindi la soluzione migliore è quella di spostare il blob ad un altro tavolo. Dovete usare una chiave primaria condivisa? Perché non fare qualcosa di simile a questo:

public class MyBlobWrapper {
    @Id
    public Long getId() {
       return id;
    }
    @Lob
    public String getBlob() {
        return blob;
    }
    @OneToOne(fetch=FetchType.LAZY,optional=false) 
    public MyClass getParent() {
        return parent;
    }
}

Altri suggerimenti

Invece di fare equilibristics con annotazioni Hibernate, si può solo cercare convertire il campo da String in Clob (o Blob):

@Lob  
@Basic(fetch=FetchType.LAZY)  
@Column(name = "FIELD_COLUMN")  
public Clob getFieldClob() {  
  return fieldClob;  
}  

public void setFieldClob(Clob fieldClob) {  
  this.fieldClob = fieldClob;  
}  

@Transient  
public String getField()  
{  
  if (this.getFieldClob()==null){  
    return null;  
  }  
  try {  
    return MyOwnUtils.readStream(this.getFieldClob().getCharacterStream());  
  } catch (Exception e) {  
    e.printStackTrace();  
  }  

  return null;  
}  

public void setField(String field)  
{  
  this.fieldClob = Hibernate.createClob(field);  
} 

Ha lavorato per me (il campo ha iniziato a caricare pigramente, su Oracle).

Dal momento in cui sembra essere usando Hibernate Mi chiedo se il problema è legato alla seguente funzionalità di sospensione:

Utilizzando pigro Proprietà Recupero

  

Hibernate3 sostiene il recupero pigro dei singoli immobili. Questo   tecnica di ottimizzazione è anche conosciuto come gruppi a palla. Si prega di notare che   questo è per lo più una funzione di marketing; ottimizzando fila legge è molto più   importante di ottimizzazione della colonna di legge. Tuttavia, solo il caricamento   alcune proprietà di una classe potrebbe essere utile in casi estremi. Per   ad esempio, quando le tabelle precedenti hanno centinaia di colonne e dei dati   modello non può essere migliorata.

     

proprietà pigro carico richiede bytecode strumentazione buildtime . Se   le vostre classi persistenti non sono migliorati, Hibernate ignorerà pigro   impostazioni di proprietà e ritorno al recupero immediato.

Bytecode Strumentazione per Hibernate Utilizzando Maven .

Old post, ma solo uno che mi ha aiutato, grazie alla @TadeuszKopec risposta.

sembra che è difficile da fare lazy loading di blob con JPA. Ho provato associazione @OneToOne, ma complica più di aiuto. Mi sono appena trasferito i byte ad un'altra classe, con nessuna associazione con MyClass (genitore dello stesso tavolo, stesso id.):

@Entity
@Table(name="MyTable")
public class MyBlobWrapper{

    @Id
    @Column(name = "id") // id of MyTable, same as MyClass
    private Long id;

    @Lob
    private byte[] bytes;   
}

@Entity
@Table(name="MyTable")
public class MyClass{

    @Id
    @Column(name = "id")
    private Long id;
    // other fields  .....
}

Basta ricordarsi di svuotare genitore, prima di salvare il blob:

 em.persist(parent);
 em.flush();
 em.merge(new MyBlobWrapper(parent_id,new byte[1000]));

Ora posso caricare il pdf da solo:

String query1 = " select PDF from MyBlobWrapper PDF where PDF.id = :id";

Sono solo principiante con APP, la speranza che aiuta.

Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top