Récupération paresseuse d’une colonne (atsortingbut de classe) avec Hibernate

Je travaille avec une vieille table qui ressemble à ceci:

+------------------+--------------+------+-----+---------+-------+ | Field | Type | Null | Key | Default | Extra | +------------------+--------------+------+-----+---------+-------+ | BINARY_DATA_ID | varchar(255) | NO | PRI | | | | BINARY_DATA | longblob | YES | | NULL | | | BINARY_DATA_NAME | varchar(255) | YES | | NULL | | +------------------+--------------+------+-----+---------+-------+ 

Le principal problème avec ceci est que la classe Java BinaryData charge la colonne BINARY_DATA , même si je n’ai besoin que de BINARY_DATA_NAME . Je sais que la meilleure solution consiste à séparer les données des méta-données (comme le nom du fichier) afin qu’elles résident dans des tables séparées. À partir de là, il est facile de charger les données paresseuses. Voilà comment cela aurait dû être fait en premier lieu.

Malheureusement, il peut ne pas être possible pour moi de faire ce qui précède en raison de contraintes organisationnelles. En guise de solution de contournement, est-il possible de charger cette colonne en utilisant des annotations au lieu de séparer les éléments dans des tableaux distincts? J’ai modifié la classe BinaryData afin qu’elle ait une classe BinaryDataData interne interne qui est @Embedded et que l’atsortingbut est @Basic(fetch=FetchType.LAZY) :

 @Entity @Table @Proxy(lazy=false) @Inheritance(strategy=InheritanceType.JOINED) public class BinaryData implements Serializable, Persistable, Cloneable { private static final long serialVersionUID = /** blah */; @Id @Column @GeneratedValue(generator="uuid") @GenericGenerator(name="uuid", strategy="uuid") private Ssortingng id; @Column private Ssortingng binaryDataName; @Embedded @Basic(fetch = FetchType.LAZY) private BinaryDataData binaryData; @Transient private Ssortingng cacheId; /** * Hibernate constructor */ public BinaryData() { /* Creates a new instance of Attachment. */} public BinaryData(byte[] binaryData, Ssortingng binaryDataName) { this.binaryData = new BinaryDataData(ArrayUtils.clone(binaryData)); this.binaryDataName = binaryDataName; } /** * Returns the BinaryData byte stream. * * @return binaryData byte stream */ @Embedded @Basic(fetch = FetchType.LAZY) public byte[] getBinaryData() { if (this.binaryData == null) { return new byte[0]; } return binaryData.getActualData(); } @Embeddable public static class BinaryDataData implements Serializable { @Column(length=32*1024*1024, columnDefinition="longblob", name="BINARY_DATA") @Lob private byte[] actualData; public BinaryDataData() { } public BinaryDataData(byte[] data) { this.actualData = data; } public byte[] getActualData() { if (this.actualData == null) { return new byte[0]; } return this.actualData; } public void setBinaryData(byte[] newData) { this.actualData = newData; } @Override public boolean equals(Object obj) { if (this == obj) { return true; } if (obj == null) { return false; } if (!(obj instanceof BinaryDataData)) { return false; } final BinaryDataData other = (BinaryDataData) obj; if (!Arrays.equals(actualData, other.actualData)) { return false; } return true; } } /** onwards... */ 

Malheureusement cela ne fonctionne pas. Le SQL que je vois montre toujours une extraction complète de l’object même si les données binarys ne sont pas demandées:

 select ideaattach0_.BINARY_DATA_ID as BINARY1_9_, ideaattach0_1_.BINARY_DATA as BINARY2_9_, ideaattach0_1_.BINARY_DATA_NAME as BINARY3_9_, ideaattach0_.IDEA_BUCKET_ID as IDEA2_136_ from IDEA_ATTACHMENT ideaattach0_ inner join BINARY_DATA ideaattach0_1_ on ideaattach0_.BINARY_DATA_ID=ideaattach0_1_.BINARY_DATA_ID where ideaattach0_.BINARY_DATA_ID=? 

Des idées? Je vous remercie.

De Hibernate, Chapitre 19. Améliorer les performances :

Récupération d’atsortingbut paresseux: un atsortingbut ou une association à valeur unique est récupéré lors de l’access à la variable d’instance. Cette approche nécessite une instrumentation en bytecode au moment de la construction et est rarement nécessaire.

Pour le projet maven, il est nécessaire d’append la dépendance du plugin suivante dans pom.xml:

  org.hibernate.orm.tooling hibernate-enhance-maven-plugin ${hibernate.version}    true true   enhance     

Je l’ai vérifié dans mon projet et ça marche, exemple d’entité:

 @Entity(name = "processing_record") public class ProcessingRecord { /** * Why uuid: https://www.clever-cloud.com/blog/engineering/2015/05/20/why-auto-increment-is-a-terrible-idea/ */ @Id @Column(name = "record_id") @org.hibernate.annotations.Type(type = "pg-uuid") private UUID id; ... /** * Processing result. */ @Column(name = "result") @Basic(fetch = FetchType.LAZY) private Ssortingng result; ... 

Pour plus de détails, consultez l’article suivant: LINK

Je suis au courant de la date de cette interrogation; cependant, j’aurais également tenté d’utiliser une classe de valeur de projection mappant en tant que sous-ensemble des colonnes et d’utiliser cette projection avec une requête nommée spécifiée qui instancie cet object de valeur de projection au lieu du object de base étant référencé ici.

Je travaille sur une solution qui utilise cette méthode, je n’ai donc pas d’exemple complet à l’heure actuelle. Cependant, l’idée de base est que vous créiez une requête JPA qui utilise la syntaxe “select NEW Projection_Object_Target”, les champs étant directement référencés dans le constructeur de “Projection_Object_Target”.

IE Utilisez une expression de constructeur comme suit:

 SELECT NEW fully.qualified.package.name.ProjectionObject(baseObject.column_target_0,baseObject.column_target_1,...,baseObject.column_target_n) FROM BaseObjectMappedInDBTable AS baseObject 

Exemple d’utilisation générique:

 Ssortingng queryStr = "SELECT NEW fully.qualified.package.name.ProjectionObject(baseObject.column_target_0) " + "FROM BaseObjectMappedInTable AS baseObject"; TypedQuery query = em.createQuery(queryStr, ProjectionObject.class); List results = query.getResultList();