How to use multiple @Onetoone & @OnetoMany annotation

Viewed 177

I'm newbie in Spring boot and making first time an experimental app. This app consist on 3 classes / tables:

Account:

  • has an account numbers that can be call by JournalEntryDetail, so I get @onetoone relation

JournalEntryMaster:

  • can have many JournalEntryDetail
  • I use here @OnetoMany annotation

JournalEntryDetail:

  • can have one JournalEntryMaster
  • Foreign key to Account, as Account number should be equal b/w JournalEntDetail & Account table

I get an error:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 
'entityManagerFactory' defined in class path resource 
[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation 
of init method failed; nested exception is org.hibernate.AnnotationException: @Column(s) not 
allowed on a @OneToOne property: com.accounts.entity.JournalEntryMaster.jvNumber

I can understand what does error means but unfortunately I did not find solution, so I came here. Any one could advise will be appreciated.

I copy entities hereunder:

accountnumber

public class Account {
@Id
@GeneratedValue

@Column(name="account_id")
private Long id;

@Column(name="account_number")
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;

@ManyToOne(cascade = CascadeType.ALL)
private JournalEntryDetail journalEntryDetail;

JournalEntryMaster

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class JournalEntryMaster {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;

@OneToOne
@Column(name="jv_number")
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;

@OneToMany(targetEntity = JournalEntryDetail.class, cascade = CascadeType.ALL)
private Set<JournalEntryDetail> journalEntryDetail = new HashSet<>();
}

JourEntryDetail

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString

public class JournalEntryDetail {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name="account_number")
private Long accountNumber;

@Enumerated(EnumType.STRING)
@Column(name="jv_detail_drcr")
private DrOrCrSide DrCr;

@Column(name="amount")
private Double Amount;

@Column(name="memo")
private String Memo;

@ManyToOne
@JoinColumn(name = "jv", referencedColumnName = "id")
private JournalEntryMaster jv;

@JoinColumn(name = "account_fk_jv", referencedColumnName = "account_number")
@OneToOne(targetEntity = Account.class, cascade = CascadeType.ALL)
private Account account_number;

@JoinColumn(name = "jvnumber_fk", referencedColumnName = "jv_number")
@OneToOne(targetEntity = JournalEntryMaster.class, cascade = CascadeType.ALL)
private JournalEntryMaster jvNumber;
2 Answers

In

public class JournalEntryMaster {
...
@OneToOne <-- remove this annotation
@Column(name="jv_number")
private Long jvNumber; 

You use Long for the jvNumber. If this is just a database column and its not related to an entity, don't use @OneToOne. You can remove the annotation and your error @Column(s) not allowed on a @OneToOne property: com.accounts.entity.JournalEntryMaster.jvNumber will disappear.

On the other hand, if it is related to an entity, you have to use JoinColumn instead of Column and use your EntityClass instead of Long.

Remove @OneToOne from JournalEntryMaster above @Column(name="jv_number") private Long jvNumber and relation of JournalEntryDetail with JournalEntryMaster is @ManyToOne not @OneToOne. you give two relation together for one table in JournalEntryDetail

remove:

@JoinColumn(name = "jvnumber_fk", referencedColumnName = "jv_number")
@OneToOne(targetEntity = JournalEntryMaster.class, cascade = CascadeType.ALL)
private JournalEntryMaster jvNumber;

Here down modified code:

JournalEntryMaster

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString
public class JournalEntryMaster {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name="id")
private Long id;

@Column(name="jv_number")
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;

@OneToMany(targetEntity = JournalEntryDetail.class, cascade = CascadeType.ALL)
private Set<JournalEntryDetail> journalEntryDetail = new HashSet<>();
}

JourEntryDetail

@Entity
@Getter
@Setter
@AllArgsConstructor
@NoArgsConstructor
@EqualsAndHashCode
@ToString

public class JournalEntryDetail {

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;

@Column(name="account_number")
private Long accountNumber;

@Enumerated(EnumType.STRING)
@Column(name="jv_detail_drcr")
private DrOrCrSide DrCr;

@Column(name="amount")
private Double Amount;

@Column(name="memo")
private String Memo;

@ManyToOne
@JoinColumn(name = "jv", referencedColumnName = "id")
private JournalEntryMaster jv;

@JoinColumn(name = "account_fk_jv", referencedColumnName = "account_number")
@OneToOne(targetEntity = Account.class, cascade = CascadeType.ALL)
private Account account_number;
Related