hibernate/hibernate-orm · error · AnnotationException
Association '%s' is 'mappedBy' a property '%s' of entity '%s
Error message
Association '%s' is 'mappedBy' a property '%s' of entity '%s' which maps to a formula
What it means
The property this association is 'mappedBy' resolves to a value whose first selectable is not a real Column but a formula (@Formula / @JoinColumnOrFormula). Hibernate needs one concrete column to derive the inverse side's join/order column, and a formula cannot serve, so the mapping is refused. (Note the message itself prints the property-holder path twice due to an upstream formatting quirk.)
Source
Thrown at hibernate-core/src/main/java/org/hibernate/boot/model/internal/AnnotatedJoinColumns.java:619
}
final var mappedByProperty =
collector.getEntityBinding( getMappedByEntityName() )
.getProperty( getMappedByPropertyName() );
final var value = (SimpleValue) mappedByProperty.getValue();
if ( value.getSelectables().isEmpty() ) {
throw new AnnotationException(
String.format(
Locale.ENGLISH,
"Association '%s' is 'mappedBy' a property '%s' of entity '%s' with no columns",
getPropertyHolder().getPath(),
getMappedByPropertyName(),
getMappedByEntityName()
)
);
}
if ( !(value.getSelectables().get( 0 ) instanceof Column column) ) {
throw new AnnotationException(
String.format(
Locale.ENGLISH,
"Association '%s' is 'mappedBy' a property '%s' of entity '%s' which maps to a formula",
getPropertyHolder().getPath(),
getMappedByPropertyName(),
getPropertyHolder().getPath()
)
);
}
if ( value.getSelectables().size() > 1 ) {
throw new AnnotationException(
String.format(
Locale.ENGLISH,
"Association '%s' is 'mappedBy' a property '%s' of entity '%s' with multiple columns",
getPropertyHolder().getPath(),
getMappedByPropertyName(),
getPropertyHolder().getPath()
)View on GitHub (pinned to fad1729dce)
Solutions
- Replace the @JoinFormula/@Formula on the owning side with a real @JoinColumn so a physical column backs the association.
- If the formula join is mandatory, drop mappedBy and map the collection with an explicit @JoinTable or leave it unidirectional.
- Re-check that mappedBy targets the association property, not a separate formula-mapped attribute.
Example fix
// before
@Entity
class Team {
@ManyToOne
@JoinColumnOrFormula(formula = @JoinFormula(value = "upper(code)", referencedColumnName = "code"))
League league; // formula, not a column
}
@Entity
class League {
@OneToMany(mappedBy = "league") // -> error: mapped by a formula
List<Team> teams;
}
// after
@Entity
class Team {
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "league_code", referencedColumnName = "code")
League league;
} Defensive patterns
Strategy: validation
Validate before calling
// Guard: the mappedBy owner must not be formula-backed
String mappedBy = "league";
Field owner = Team.class.getDeclaredField(mappedBy);
if (owner.getAnnotation(JoinFormula.class) != null
|| Arrays.stream(owner.getAnnotationsByType(JoinColumnOrFormula.class))
.anyMatch(j -> j.formula() != null && !j.formula().value().isEmpty())) {
throw new IllegalStateException("mappedBy owner '" + mappedBy + "' is formula-backed");
} Try / catch
try {
factory = cfg.buildSessionFactory();
} catch (AnnotationException e) {
// 'which maps to a formula' -> replace the @JoinFormula with a real
// @JoinColumn or map the collection via @JoinTable
throw newConfigurationException("Formula-backed mappedBy", e);
} Prevention
- Use @JoinColumn for associations you plan to make bidirectional; reserve @JoinFormula for read-only unidirectional joins.
- If a formula join is required, keep the collection side unidirectional or use an explicit join table.
When it happens
Trigger: '@OneToMany(mappedBy = "x")' where the owning property x is a @ManyToOne referenced through @JoinColumnOrFormula(..., formula=@JoinFormula(...)); the owning side's FK is defined with @Formula instead of @JoinColumn; legacy @org.hibernate.annotations.Formula on the mapped property.
Common situations: Joining by an expression (e.g. concatenation or computed key) and then trying to hang a mappedBy collection off it; converting a working unidirectional formula join to a bidirectional one.
Related errors
- Association '%s' of entity '%s' is 'mappedBy' a different en
- Association '%s' is 'mappedBy' a property '%s' of entity '%s
- Association '%s' is 'mappedBy' a property '%s' of entity '%s
- Class '<componentClassName>' is an '@Embeddable' type and ma
- Property '<propertyName>' may not be annotated '@BatchSize'
AI-assisted analysis of hibernate/hibernate-orm@fad1729dce (2026-08-22).
Data as JSON: /api/errors/3242f8be5a1cb59e.
Report an issue: GitHub.