2017-07-20 3 views
1

Je veux choisir quand chargement du jeu avec LazyJPA + Hibernate OGM + Lazy Initialisation avec Jackson Datatype Mise en veille prolongée

Ceci est mon entité produit

@Entity 
public class Product { 

    @Id 
    @GeneratedValue(strategy = GenerationType.IDENTITY) 
    @Type(type = "objectid") 
    private String id; 
    private String name; 

    @ManyToMany(fetch = FetchType.LAZY) 
    private Set<Category> categories; 

Ceci est mon AbstractService

public abstract class AbstractService<T> { 

    private Class<T> entityClass; 

    public AbstractService(Class<T> entityClass){ 
     this.entityClass=entityClass; 

    public List<T> findAll(){ 
     Query nativeQuery = getEntityManager().createNativeQuery("{}", entityClass); 
     return getEntityManager().createNativeQuery("{}",entityClass).getResultList(); 
    } 
} 

ceci i mon ProductService

@Stateless 
public class ProductService extends AbstractService<Product> { 

    @PersistenceContext(unitName = "name-db") 
    private EntityManager em; 

    public ProductService() { 
     super(Product.class); 
    } 

    @Override 
    protected EntityManager getEntityManager() { 
     return em; 
    } 

ceci est ma méthode d'essai

@Test 
    public void testFindAllProducts()throws Exception { 
     List<Product> products = productService.findAll(); 
     for (Product p: 
      products) { 
      //Hibernate.initialize(p.getCategories()); 
      System.out.println(p.toString()); 
     } 
    } 

Je voudrais utiliser un proxy pour initialiser les catégories chaque fois que je besoin

Mise en veille prolongée (y compris Hibernate OGM) prend en charge le chargement à l'aide de proxy objets au lieu de instances des classes d'entités. Hibernate utilise des proxies comme solution pour «séparer» les données interconnectées reçues d'une base de données en de plus petites pièces qui peuvent être facilement stockées en mémoire. Il peut être utile d'être conscient que Hibernate génère dynamiquement des proxies pour les objets qui sont chargés paresseusement. Les chances sont, vous n'êtes pas au courant des objets proxy, et ne sera pas jusqu'à ce que vous obtenez certaines exceptions de type LazyInitializationException, ou jusqu'à ce que vous essayiez de tester le chargement paresseux dans un débogueur et notez la présence de certains objets non-null avec propriétés nulles. Ne sachant pas quand vous êtes « travailler » sur un objet proxy au lieu d'un objet d'une entité peut entraîner des résultats étranges ou exceptions

Comment puis-je mettre en œuvre une procuration?

Répondre

1

Vous n'avez pas besoin d'implémenter un proxy, Hibernate OGM en instanciera un si nécessaire.

Dans ce cas, pour chaque résultat, la valeur renvoyée par p.getCategories() doit être un proxy.

+0

En fait, mais lorsque je tente de l'obtenir j'accéder _Caused par: org.hibernate .LazyInitializationException: impossible d'initialiser paresseusement une collection de rôle_ – Pako

+0

Vous devez vérifier que tout se passe dans une transaction en cours d'exécution. Hibernate OGM nécessite toujours une démarcation des transactions, même avec MongoDB. – Davide

0

la deuxième assert échec

@Test 
public void testLazyHibernate(){ 
    List<Product> products = productService.findAll(); 
    for (Product p: 
      products) { 
     assertFalse(Hibernate.isInitialized(p.getCategories())); 
     Set<Category> categories = p.getCategories(); 
     assertTrue(Hibernate.isInitialized(categories)); 
    } 
} 

Je voudrais utiliser jackson-veille prolongée-type de données, mais ne fonctionne pas

@Provider 
@Produces(MediaType.APPLICATION_JSON) 
@Consumes(MediaType.APPLICATION_JSON) 
public class MyJacksonJsonProvider implements ContextResolver<ObjectMapper> { 

    private static final ObjectMapper MAPPER = new ObjectMapper(); 
    private Hibernate5Module hbm5; 

    static { 
     MAPPER.enable(SerializationFeature.INDENT_OUTPUT); 
     MAPPER.registerModule(new SimpleModule().addSerializer(Product.class, new ProductSerializer())); 
     MAPPER.registerModule(new Hibernate5Module().enable(Hibernate5Module.Feature.FORCE_LAZY_LOADING)); 

      } 

    public MyJacksonJsonProvider() { 
     hbm5 = new Hibernate5Module(); 
    hbm5.configure(Hibernate5Module.Feature.FORCE_LAZY_LOADING,true); 
     hbm5.enable(Hibernate5Module.Feature.FORCE_LAZY_LOADING); 

     System.out.println("Instantiate MyJacksonJsonProvider"); 
    } 

    @Override 
    public ObjectMapper getContext(Class<?> type) { 
     System.out.println("MyJacksonProvider.getContext() called with type: "+type); 
     return MAPPER; 
    } 
}