Spring Boot多@OneToOne与@OneToMany注解使用报错及解决方案咨询
Hey there! Let's tackle this error and get your Spring Boot entity mappings sorted out properly.
First, let's break down the error you're seeing:
org.hibernate.AnnotationException: @Column(s) not allowed on a @OneToOne property: com.accounts.entity.JournalEntryMaster.jvNumber
This happens because you've applied @Column to a field marked with @OneToOne—these two annotations don’t play together. @OneToOne defines a relationship between two entities, while @Column maps a simple database column to a Java field. Looking at your code, jvNumber should just be a regular field on JournalEntryMaster, not an entity relationship.
Let's fix each entity one by one, aligning with your business requirements:
1. Corrected Account Entity
Your requirement states that JournalEntryDetail references Account, so the relationship should be one Account to many JournalEntryDetails (since multiple entries can link to the same account). I’ve fixed the relationship direction and cleaned up naming:
@Entity @Getter @Setter @AllArgsConstructor @NoArgsConstructor public class Account { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="account_id") private Long id; @Column(name="account_number", nullable = false, unique = true) private Long accountNumber; @Column(name="account_name") private String accountName; @Enumerated(EnumType.STRING) @Column(name="dr_or_credit") private DrOrCrSide drOrCrSide; @Enumerated(EnumType.STRING) @Column(name="account_type") private AccountType accountType; // One Account can have multiple JournalEntryDetails @OneToMany(mappedBy = "account", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<JournalEntryDetail> journalEntryDetails = new HashSet<>(); }
2. Corrected JournalEntryMaster Entity
Removed the invalid @OneToOne from jvNumber, fixed the @OneToMany mapping (added mappedBy to link with the child entity's jv field), and standardized field naming:
@Entity @Getter @Setter @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode(exclude = "journalEntryDetails") @ToString(exclude = "journalEntryDetails") public class JournalEntryMaster { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Column(name="id") private Long id; @Column(name="jv_number", nullable = false, unique = true) private Long jvNumber; @Column(name="jv_master_date") private Date date; @Column(name="jv_reference_no") private String referenceNo; @Column(name="memo") private String memo; @Column(name="posted") private boolean posted; // One JournalEntryMaster has many JournalEntryDetails @OneToMany(mappedBy = "jv", cascade = CascadeType.ALL, fetch = FetchType.LAZY) private Set<JournalEntryDetail> journalEntryDetails = new HashSet<>(); }
3. Corrected JournalEntryDetail Entity
Fixed the Account relationship to @ManyToOne (since multiple details can share one account), removed the redundant jvNumber relationship (you can get this from the linked jv), and cleaned up naming:
@Entity @Getter @Setter @AllArgsConstructor @NoArgsConstructor @EqualsAndHashCode(exclude = {"jv", "account"}) @ToString(exclude = {"jv", "account"}) public class JournalEntryDetail { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @Enumerated(EnumType.STRING) @Column(name="jv_detail_drcr") private DrOrCrSide drCr; @Column(name="amount") private Double amount; @Column(name="memo") private String memo; // Many JournalEntryDetails belong to one JournalEntryMaster @ManyToOne @JoinColumn(name = "jv_master_id", referencedColumnName = "id", nullable = false) private JournalEntryMaster jv; // Many JournalEntryDetails link to one Account @ManyToOne @JoinColumn(name = "account_fk_jv", referencedColumnName = "account_number", nullable = false) private Account account; }
Key Fixes & Notes
- Removed invalid annotation combination:
@Columnon@OneToOnewas the root cause of your initial error. - Fixed relationship directions: Ensured relationships match your business logic (one-to-many where needed instead of reversed mappings).
- Added
mappedByfor bidirectional relationships: This tells Hibernate which side of the relationship owns the foreign key, avoiding unnecessary join tables. - Standardized naming: Used Java camelCase for fields and SQL snake_case for column names to follow best practices.
- Added constraints: Marked critical fields like
account_numberandjv_numberasnullable = falseanduniqueto enforce data integrity.
内容的提问来源于stack exchange,提问作者Seeschon

