hibernate/hibernate-orm · error · PropertyAccessException

Could not chain accessor because result of previous accessor

Error message

Could not chain accessor because result of previous accessor was null

What it means

ChainedPropertyAccessImpl applies a chain of getters for a dotted property path (nested embeddables). getForInsert walks the chain and throws PropertyAccessException 'Could not chain accessor because result of previous accessor was null' the moment an intermediate link is null, because the next getter cannot be invoked on null. (The plain get() path instead fails on its non-null contract.)

Source

Thrown at hibernate-core/src/main/java/org/hibernate/property/access/internal/ChainedPropertyAccessImpl.java:62

	public Setter getSetter() {
		return this;
	}

	@Override
	public @Nullable Object get(Object owner) {
		@Nullable Object result = owner;
		for ( int i = 0; i < propertyAccesses.length; i++ ) {
			result = propertyAccesses[i].getGetter().get( NullnessUtil.castNonNull( result ) );
		}
		return result;
	}

	@Override
	public @Nullable Object getForInsert(Object owner, Map<Object, Object> mergeMap, SharedSessionContractImplementor session) {
		@Nullable Object result = owner;
		for ( int i = 0; i < propertyAccesses.length; i++ ) {
			if ( result == null ) {
				throw new PropertyAccessException( "Could not chain accessor because result of previous accessor was null" );
			}
			result = propertyAccesses[i].getGetter().getForInsert( result, mergeMap, session );
		}
		return result;
	}

	@Override
	public void set(Object target, @Nullable Object value) {
		throw new UnsupportedOperationException();
	}

	@Override
	public Class<?> getReturnTypeClass() {
		return propertyAccesses[propertyAccesses.length - 1].getGetter().getReturnTypeClass();
	}

	@Override
	public Type getReturnType() {

View on GitHub (pinned to fad1729dce)

Solutions

  1. Initialize intermediate embeddables eagerly: private Address address = new Address();
  2. Validate that the full path is populated before persist, or populate missing links in a @PrePersist callback
  3. Flatten the mapping so the leaf is reached without a chain, if null intermediates are legitimate in your domain
  4. Review entity factories and mapping code to always construct the complete embeddable hierarchy

Example fix

// before
@Entity public class Customer {
    @Embedded private Details details; // never initialized
}

// after
@Entity public class Customer {
    @Embedded private Details details = new Details();
}
@Embeddable public class Details {
    @Embedded private Address address = new Address();
}
Defensive patterns

Strategy: validation

Validate before calling

if (customer.getDetails() == null || customer.getDetails().getAddress() == null) {
    throw new IllegalStateException("Nested embeddables must be initialized before persist");
}
session.persist(customer);

Try / catch

try {
    session.persist(customer);
} catch (org.hibernate.PropertyAccessException e) {
    if (e.getMessage().contains("chain accessor")) {
        // an intermediate embeddable was null: initialize the chain and retry
    }
}

Prevention

When it happens

Trigger: Persisting or flushing an entity whose mapping uses a chained property path (e.g., details.address.city across nested @Embedded values) while an intermediate embeddable instance is null at insert time.

Common situations: Embeddables never initialized in constructors or factory methods; builder/DTO-mapping code that skips optional sections and leaves intermediate objects null; inserts that populate only the leaf value; refactoring flat fields into nested embeddables without initializing them.

Related errors


AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22). Data as JSON: /api/errors/f6cffc1310c487ba. Report an issue: GitHub.