Hibernate忽略@OneToMany映射的@JoinColumn自定义值问题排查
Hey there, let's break down why your Hibernate association is still clinging to the old state_name column instead of the newly configured state_nm, and how to fix it without switching to mappedBy.
The Root Cause
When working with a unidirectional @OneToMany association without mappedBy, Hibernate needs aligned @JoinColumn configurations across both sides of the relationship (even if your code treats it as "unidirectional"). Here's what went wrong:
- You updated the
@JoinColumn(name="state_nm")on theStateentity'scitieslist, which prompted Hibernate to create thestate_nmcolumn in thecitytable. - But you didn't update the
Cityentity's@ManyToOneassociation to point to the samestate_nmcolumn. Hibernate defaulted to generating a foreign key column using the pattern{associationEntityName}_{primaryKeyColumnName}— which in this case isstate_name(since yourStateentity's primary key isname).
This mismatch means Hibernate tries to join on state_name (which holds your actual data) while your new configuration expects state_nm (which is NULL), resulting in empty association results.
The Fix (Unidirectional @OneToMany Style)
You just need to align the @JoinColumn configuration on the City entity's state field to match the one on State. Here's the corrected code:
Updated City Entity
@Table(name="city") @Entity public class City { @Id @Column(name="name") String name; @Column(name="population") String population; @ManyToOne @JoinColumn(name="state_nm") // This is the critical missing piece! State state; // getters/setters }
Updated State Entity (your existing code is valid, included for clarity)
@Table(name="state") @Entity public class State { @Id @Column(name="name") String name; @Column(name="population") String population; @OneToMany(cascade=CascadeType.ALL, fetch=FetchType.EAGER) @JoinColumn(name="state_nm") // Keep this configuration as-is List<City> cities; @ManyToOne Country country; // getters/setters }
Database Cleanup
Next, migrate your existing data from the old state_name column to the new state_nm column. Run this SQL in your MySQL instance:
UPDATE city SET state_nm = state_name;
Once the data is migrated, you can safely drop the old state_name column to avoid future confusion:
ALTER TABLE city DROP COLUMN state_name;
Why This Works
By adding @JoinColumn(name="state_nm") to the City entity's state field, you're explicitly telling Hibernate that the foreign key linking City to State is state_nm — matching exactly what you configured on the State side. Now Hibernate will use this column for all association queries and operations, so your cities list will populate correctly.
内容的提问来源于stack exchange,提问作者samshers

