复合主键映射异常:父表parent_id无法写入子表问题求助
Fixing Parent ID Not Saving Correctly in Child Table with JPA IDClass
Alright, let's figure out why your child_table is storing parent_id as 0 and fix this mapping issue step by step. The problem stems from several misconfigurations in your JPA entity mappings and relationship handling.
Key Issues in Your Current Code
- Wrong placement of
@GeneratedValue: You applied the table generator annotation to theparentassociation field instead of thechildIdfield—this makes no sense for generating the child's auto-increment ID. - Incorrect
@JoinColumnsettings: Theinsertable=false, updatable=falseon theparentfield tells JPA not to write or update this column, but we need JPA to populate it with the parent's generated ID. - Mismatched IDClass mapping: Your
ChildPKdefinesparentIdandchildIdas the composite key, but yourChildentity doesn't have a correspondingparentIdfield (you tried to use theparentassociation directly as an ID part), which confuses JPA. - Unmaintained bidirectional relationship: You didn't link the
Childto itsParentbefore persisting—JPA can't guess this association automatically.
Corrected Code Implementations
1. ChildPK Class (Minor Adjustment)
Ensure the field names match exactly what's in the Child entity:
@Getter @Setter @EqualsAndHashCode public class ChildPK implements Serializable { private static final long serialVersionUID = 1L; private int parentId; // Matches Child.parentId private int childId; // Matches Child.childId }
2. Child Entity (Major Fixes)
We'll explicitly map the composite key fields and properly link the parent association:
@Getter @Setter @EqualsAndHashCode @Entity @IdClass(ChildPK.class) @Table(name = "child_table") public class Child implements Serializable { private static final long serialVersionUID = 1L; // Correctly apply the table generator to childId @Id @TableGenerator( name = "child_id_generator", table = "id_sequence", initialValue = 1, allocationSize = 1 ) @GeneratedValue(strategy = GenerationType.TABLE, generator = "child_id_generator") @Column(name="child_id") private int childId; // Map the parent_id part of the composite key @Id @Column(name = "parent_id", nullable = false) private int parentId; // Link to Parent without marking this as an ID (parentId already handles that) @ManyToOne(fetch = FetchType.LAZY) @JoinColumn(name = "parent_id", insertable = false, updatable = false) private Parent parent; // Helper method to sync parent and parentId automatically public void setParent(Parent parent) { this.parent = parent; if (parent != null) { this.parentId = parent.getParentId(); } } }
3. Parent Entity (Add Relationship Maintenance)
Add a helper method to keep the bidirectional relationship in sync:
@Setter @Getter @Entity @Table(name = "parent_table") public class Parent implements Serializable { private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name = "parent_id") private int parentId; @OneToMany(mappedBy = "parent", cascade = CascadeType.ALL, orphanRemoval = true) private List<Child> childs = new ArrayList<>(); // Add child and automatically set its parent reference public void addChild(Child child) { childs.add(child); child.setParent(this); // Critical: syncs the child's parent and parentId } }
4. Persistence Logic (Fix Saving Flow)
Use the helper method to ensure the parent-child link is established before persisting:
class MainClass { public static void main(String[] args) { Parent parent = new Parent(); Child child = new Child(); parent.addChild(child); // This handles the relationship sync entityManager.persist(parent); // Now child_table will get the correct parent_id } }
Why This Works
- The
@GeneratedValueis now correctly attached tochildId, so JPA generates the auto-increment ID for the child. - The
parentIdfield inChildmaps directly to the composite key, allowing JPA to write the parent's ID to the child table. - The
parentassociation usesinsertable=false, updatable=falseto avoid conflicting with theparentIdfield, while still maintaining the relationship for queries. - The helper methods ensure the bidirectional relationship is properly maintained, so when you persist the parent, JPA knows exactly which parent ID to write to the child records.
内容的提问来源于stack exchange,提问作者saradhi
相关产品推荐
相关产品推荐

