Tout d'abord, quelques clarifications à la réponse de KLE :
L'association un-à-un sans contrainte (nullable) est la seule qui ne peut pas être mandatée sans instrumentation de bytecode. La raison en est que l'entité propriétaire DOIT savoir si la propriété d'association doit contenir un objet proxy ou NULL et elle ne peut pas déterminer cela en regardant les colonnes de sa table de base car un à un est normalement mappé via PK partagé, donc il doit être récupéré avec impatience de toute façon, rendant le proxy inutile. Voici une explication plus détaillée .
les associations plusieurs-à-un (et un-à-plusieurs, évidemment) ne souffrent pas de ce problème. L'entité propriétaire peut facilement vérifier son propre FK (et dans le cas d'un à plusieurs, un proxy de collecte vide est créé initialement et rempli à la demande), de sorte que l'association peut être paresseuse.
Remplacer un à un par un à plusieurs n'est presque jamais une bonne idée. Vous pouvez le remplacer par plusieurs à un, mais il existe d'autres options (peut-être meilleures).
Rob H. a un point valide, mais vous ne pourrez peut-être pas l'implémenter en fonction de votre modèle (par exemple si votre association un à un est annulable).
Maintenant, en ce qui concerne la question d'origine:
A) @ManyToOne(fetch=FetchType.LAZY)
devrait très bien fonctionner. Êtes-vous sûr qu'il n'est pas écrasé dans la requête elle-même? Il est possible de spécifier join fetch
en HQL et / ou de définir explicitement le mode d'extraction via l'API Criteria qui aurait priorité sur l'annotation de classe. Si ce n'est pas le cas et que vous rencontrez toujours des problèmes, veuillez publier vos classes, votre requête et le SQL résultant pour une conversation plus précise.
B) @OneToOne
est plus délicat. Si elle n'est certainement pas annulable, suivez la suggestion de Rob H. et spécifiez-la comme telle:
@OneToOne(optional = false, fetch = FetchType.LAZY)
Sinon, si vous pouvez changer votre base de données (ajoutez une colonne de clé étrangère à la table propriétaire), faites-le et mappez-la comme "jointe":
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="other_entity_fk")
public OtherEntity getOther()
et dans OtherEntity:
@OneToOne(mappedBy = "other")
public OwnerEntity getOwner()
Si vous ne pouvez pas faire cela (et ne pouvez pas vivre avec une récupération avide), l'instrumentation de bytecode est votre seule option. Je dois cependant être d'accord avec CPerkins - si vous en avez 80 !!! rejoint en raison d'associations OneToOne désireuses, vous avez des problèmes plus importants que celui-ci :-)
one-to-one
avec une formule commeselect other_entity.id from other_entity where id = other_entity.id
. Bien sûr, ce n'est pas idéal pour les performances des requêtes.