public boolean isReachable(Object traversableObject, Path.Node traversableProperty, Class<?> rootBeanType, Path pathToTraversableObject, ElementType elementType) { //lazy, don't load return Hibernate.isInitialized( traversableObject ) && Hibernate.isPropertyInitialized( traversableObject, traversableProperty.getName() ); }
@Advice.OnMethodExit static void exit(@Advice.This Object self, @Advice.Argument(0) Map<?, ?> argument, @MappedBy String mappedBy) { if ( argument != null && Hibernate.isPropertyInitialized( argument, mappedBy ) ) { Object[] array = argument.values().toArray(); for ( int i = 0; i < array.length; i++ ) { if ( Hibernate.isPropertyInitialized( array[i], mappedBy ) && getter( array[i] ) != self ) { setterSelf( array[i], self ); } } } }
@Advice.OnMethodExit static void exit(@Advice.This Object self, @Advice.Argument(0) Collection<?> argument, @MappedBy String mappedBy) { if ( argument != null && Hibernate.isPropertyInitialized( argument, mappedBy ) ) { Object[] array = argument.toArray(); for ( int i = 0; i < array.length; i++ ) { if ( Hibernate.isPropertyInitialized( array[i], mappedBy ) ) { Collection<Object> c = getter( array[i] ); if ( c != self && c != null ) { c.add( self ); } } } } }
@Advice.OnMethodEnter static void enter(@FieldValue Map<?, ?> field, @Advice.Argument(0) Map<?, ?> argument, @MappedBy String mappedBy) { if ( field != null && Hibernate.isPropertyInitialized( field, mappedBy ) ) { Object[] array = field.values().toArray(); for ( int i = 0; i < array.length; i++ ) { if ( argument == null || !argument.values().contains( array[i] ) ) { setterNull( array[i], null ); } } } }
@Advice.OnMethodExit static void exit(@Advice.This Object self, @Advice.Argument(0) Collection<?> argument, @MappedBy String mappedBy) { if ( argument != null && Hibernate.isPropertyInitialized( argument, mappedBy ) ) { Object[] array = argument.toArray(); for ( int i = 0; i < array.length; i++ ) { if ( Hibernate.isPropertyInitialized( array[i], mappedBy ) && getter( array[i] ) != self ) { setterSelf( array[i], self ); } } } }
@Advice.OnMethodEnter static void enter(@FieldValue Collection<?> field, @Advice.Argument(0) Collection<?> argument, @MappedBy String mappedBy) { if ( field != null && Hibernate.isPropertyInitialized( field, mappedBy ) ) { Object[] array = field.toArray(); for ( int i = 0; i < array.length; i++ ) { if ( argument == null || !argument.contains( array[i] ) ) { setterNull( array[i], null ); } } } }
@Advice.OnMethodExit static void exit(@Advice.This Object self, @Advice.Argument(0) Object argument, @MappedBy String mappedBy) { if ( argument != null && Hibernate.isPropertyInitialized( argument, mappedBy ) ) { Collection<Object> c = getter( argument ); if ( c != null && !c.contains( self ) ) { c.add( self ); } } }
@Advice.OnMethodEnter static void enter(@Advice.This Object self, @FieldValue Collection<?> field, @Advice.Argument(0) Collection<?> argument, @MappedBy String mappedBy) { if ( field != null && Hibernate.isPropertyInitialized( field, mappedBy ) ) { Object[] array = field.toArray(); for ( int i = 0; i < array.length; i++ ) { if ( argument == null || !argument.contains( array[i] ) ) { getter( array[i] ).remove( self ); } } } }
@Advice.OnMethodEnter static void enter(@Advice.This Object self, @FieldValue Object field, @MappedBy String mappedBy) { if ( field != null && Hibernate.isPropertyInitialized( field, mappedBy ) ) { Collection<?> c = getter( field ); if ( c != null ) { c.remove( self ); } } }
@Test public void testNoTransaction() { doInHibernate( this::sessionFactory, s -> { parent = s.load( Parent.class, parentID ); assertThat( parent, notNullValue() ); assertThat( parent, not( instanceOf( HibernateProxy.class ) ) ); assertThat( parent, not( instanceOf( HibernateProxy.class ) ) ); assertFalse( isPropertyInitialized( parent, "children" ) ); } ); List children1 = parent.children; List children2 = parent.children; assertTrue( isPropertyInitialized( parent, "children" ) ); checkDirtyTracking( parent ); assertThat( children1, sameInstance( children2 ) ); assertThat( children1.size(), equalTo( CHILDREN_SIZE ) ); }
@Advice.OnMethodEnter static void enter(@FieldValue Object field, @Advice.Argument(0) Object argument, @MappedBy String mappedBy) { if ( field != null && Hibernate.isPropertyInitialized( field, mappedBy ) && argument != null ) { setterNull( field, null ); } }
@Test public void testDetach() { doInHibernate( this::sessionFactory, s -> { Parent parent = s.find( Parent.class, parentID ); assertThat( parent, notNullValue() ); assertThat( parent, not( instanceOf( HibernateProxy.class ) ) ); assertFalse( isPropertyInitialized( parent, "children" ) ); checkDirtyTracking( parent ); s.detach( parent ); s.flush(); } ); }
@Advice.OnMethodExit static void exit(@Advice.This Object self, @Advice.Argument(0) Object argument, @MappedBy String mappedBy) { if ( argument != null && Hibernate.isPropertyInitialized( argument, mappedBy ) && getter( argument ) != self ) { setterSelf( argument, self ); } }
@Test public void testRefresh() { doInHibernate( this::sessionFactory, s -> { Parent parent = s.find( Parent.class, parentID ); assertThat( parent, notNullValue() ); assertThat( parent, not( instanceOf( HibernateProxy.class ) ) ); assertFalse( isPropertyInitialized( parent, "children" ) ); checkDirtyTracking( parent ); s.refresh( parent ); s.flush(); } ); }
@Test public void testJoinFetchWithEnhancement() { Employee myEmployee = doInJPA( this::entityManagerFactory, em -> { Employee localEmployee = em.createQuery( "from Employee e left join fetch e.otherEntities", Employee.class ) .getResultList().get( 0 ); assertTrue( Hibernate.isPropertyInitialized( localEmployee, "otherEntities" ) ); return localEmployee; } ); assertEquals( "test", myEmployee.getOtherEntities().iterator().next().getId() ); }
@Test public void testManagedWithUninitializedAssociation() { // Delete the Parent doInHibernate( this::sessionFactory, s -> { Parent loadedParent = (Parent) s.createQuery( "SELECT p FROM Parent p WHERE name=:name" ) .setParameter( "name", "PARENT" ) .uniqueResult(); checkInterceptor( loadedParent, false ); assertFalse( Hibernate.isPropertyInitialized( loadedParent, "children" ) ); s.delete( loadedParent ); } ); // If the lazy relation is not fetch on cascade there is a constraint violation on commit }
@Test @TestForIssue(jiraKey = "HHH-13129") public void testDetachedOriginal() { // originalParent#children should be initialized assertTrue( Hibernate.isPropertyInitialized( originalParent, "children" ) ); checkInterceptor( originalParent, true ); // Delete the Parent doInHibernate( this::sessionFactory, s -> { s.delete( originalParent ); } ); // If the lazy relation is not fetch on cascade there is a constraint violation on commit }
@Test @TestForIssue(jiraKey = "HHH-13129") public void testDetachedWithUninitializedAssociation() { final Parent detachedParent = doInHibernate( this::sessionFactory, s -> { return s.get( Parent.class, originalParent.getId() ); } ); assertFalse( Hibernate.isPropertyInitialized( detachedParent, "children" ) ); checkInterceptor( detachedParent, false ); // Delete the detached Parent with uninitialized children doInHibernate( this::sessionFactory, s -> { s.delete( detachedParent ); } ); // If the lazy relation is not fetch on cascade there is a constraint violation on commit }
@Test @TestForIssue(jiraKey = "HHH-13129") public void testManagedWithInitializedAssociation() { // Delete the Parent doInHibernate( this::sessionFactory, s -> { Parent loadedParent = (Parent) s.createQuery( "SELECT p FROM Parent p WHERE name=:name" ) .setParameter( "name", "PARENT" ) .uniqueResult(); checkInterceptor( loadedParent, false ); loadedParent.getChildren(); assertTrue( Hibernate.isPropertyInitialized( loadedParent, "children" ) ); s.delete( loadedParent ); } ); // If the lazy relation is not fetch on cascade there is a constraint violation on commit }
@Test public void test() { doInHibernate( this::sessionFactory, s -> { TestEntity entity = s.get( TestEntity.class, entityId ); Assert.assertFalse( Hibernate.isPropertyInitialized( entity, "description" ) ); EntityPersister entityPersister = sessionFactory().getMetamodel().entityPersister( TestEntity.class ); boolean[] propertyLaziness = entityPersister.getPropertyLaziness(); assertEquals( 1, propertyLaziness.length ); assertTrue( propertyLaziness[0] ); // Make sure NonIdentifierAttribute#isLazy is consistent (HHH-10551) NonIdentifierAttribute[] properties = entityPersister.getEntityMetamodel().getProperties(); assertEquals( 1, properties.length ); assertTrue( properties[0].isLazy() ); } ); }