为什么未在JPA中为插入语句分配值 [英] Why Value is not getting assigned in JPA for insert statement

查看:37
本文介绍了为什么未在JPA中为插入语句分配值的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有几个实体类,如下所示,使用lombok进行吸气剂和吸气剂

Hi I have couple of Entity classes as below, using lombok for getter and setters

父实体类具有

@Table(name = "PARTY")
@Entity
public class Party {
        
@Id
@Column(name = "PARTY_ID")
private Long partyId;


@OneToMany(targetEntity = DVLoanParticipants.class,cascade = CascadeType.ALL)
@JoinColumn(name = "PARTY_ID")
@MapKey(name="dvpParticipantName")
@LazyCollection(LazyCollectionOption.FALSE)
private Map<String, DVLoanParticipants> dvLoanParticipantsMap;
}

子实体类具有

@Table(name = "DV_LOAN_PARTICIPANTS")
@Entity
public class DVLoanParticipants implements Serializable {

@Id
@Column(name = "PARTY_ID")
private Long partyId;

@Id
@Column(name = "DVP_PARTICIPANT_NAME")
private String dvpParticipantName;

@Column(name = "DVP_PARTICIPANT_TYPE")
private String dvpParticipantType;
}

在服务类中,我将保存操作称为

In service class i am calling save operation as

repository.save(parentEntityObject);

我能够执行更新语句,但是当我尝试为子实体类插入新行时,出现了错误提示

I am able to execute update statements ,but when i try to insert new row for child entity class i am getting an error saying

cannot insert NULL into ("ABC"."DV_LOAN_PARTICIPANTS"."PARTY_ID")

但是,如果我在保存操作之前打印出parentEntityObject,我会看到类似的值

But if i print the parentEntityObject just before the save operation i see the values like

(partyId=12345678, dvpParticipantName=XYZ, dvpParticipantType=VKP)

我看到查询形式为

insert 
 into
    DV_LOAN_PARTICIPANTS
    (DVP_PARTICIPANT_TYPE, PARTY_ID, DVP_PARTICIPANT_NAME) 
values
    (?, ?, ?)

就在保存之前,我在对象中看到了价值

Just before te save i am seeing valules in the Object

Builder=DVLoanParticipants(partyId=123456, dvpParticipantName=Builder, 
dvpParticipantType=Individual)

更新

这是值的设置部分

                DVLoanParticipants dvLoanParticipants = new 
           DVLoanParticipants();
                dvLoanParticipants.setPartyId(Long.valueOf(partyId));
                dvLoanParticipants.setDvpParticipantName("Builder");
                dvLoanParticipants.setDvpParticipantType("Individual");
                Party party = new Party();
                Map<String, DVLoanParticipants> dvLoanParticipantsMap = new 
      java.util.HashMap<>();
                dvLoanParticipantsMap.put("Builder", dvLoanParticipants);
                party.setPartyId(Long.valueOf(partyId));
                party.setDvLoanParticipantsMap(dvLoanParticipantsMap);
                repository.save(party);

我在做什么错?

推荐答案

这部分问题的根本原因:

The root cause of your problem in this part:

@OneToMany(targetEntity = DVLoanParticipants.class,cascade = CascadeType.ALL)
@JoinColumn(name = "LOAN_ID")
@MapKey(name="dvpParticipantName")
private Map<String, DVLoanParticipants> dvLoanParticipantsMap;

实际上,对于您的情况, @JoinColumn 表示:

actually for your case the column name in the @JoinColumn means:

如果联接是使用外键映射策略进行的单向OneToMany映射,则外键在目标实体的表中.

因此,为清楚起见,假设您要映射以下架构:

So, assuming for the clarity that you want to map the following schema:

create table PARTY
(
   PARTY_ID int,
   -- ...

   primary key (PARTY_ID)
);

create table DV_LOAN_PARTICIPANTS
(
   PARTY_ID int,
   DVP_PARTICIPANT_NAME varchar(50),
   DVP_PARTICIPANT_TYPE varchar(10),
   -- ...
   
   primary key (PARTY_ID, DVP_PARTICIPANT_NAME),
   foreign key (PARTY_ID) references PARTY(PARTY_ID)
);

您可以使用以下映射:

@Entity
@Table(name = "PARTY")
public class Party
{
   @Id
   @Column(name = "PARTY_ID")
   private Long partyId;

   // I use fetch = FetchType.EAGER instead of deprecated @LazyCollection(LazyCollectionOption.FALSE)
   // targetEntity = DVLoanParticipants.class is redundant here
   @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
   @JoinColumn(name = "PARTY_ID") // this is DV_LOAN_PARTICIPANTS.PARTY_ID column
   @MapKey(name = "dvpParticipantName")
   private Map<String, DVLoanParticipants> dvLoanParticipantsMap;
   
   public Party()
   {
      dvLoanParticipantsMap = new HashMap<>();
   }

   // getters / setters

   public void addParticipant(DVLoanParticipants p)
   {
      this.dvLoanParticipantsMap.put(p.getDvpParticipantName(), p);
      p.setPartyId(getPartyId());
   }
}

@Entity
@Table(name = "DV_LOAN_PARTICIPANTS")
public class DVLoanParticipants implements Serializable
{
   @Id
   @Column(name = "PARTY_ID")
   private Long partyId;

   @Id
   @Column(name = "DVP_PARTICIPANT_NAME")
   private String dvpParticipantName;

   @Column(name = "DVP_PARTICIPANT_TYPE")
   private String dvpParticipantType;

   // getters / setters
}

以及如何保存的示例:

Party party = new Party();
party.setPartyId(2L);

// ...
DVLoanParticipants part1 = new DVLoanParticipants();
part1.setDvpParticipantName("Name 3");
part1.setDvpParticipantType("T1");
      
DVLoanParticipants part2 = new DVLoanParticipants();
part2.setDvpParticipantName("Name 4");
part2.setDvpParticipantType("T1");

party.addParticipant(part1);
party.addParticipant(part2);

repository.save(party);

和一些注意事项:

  1. LazyCollectionOption.TRUE LazyCollectionOption.FALSE 值为

  1. The LazyCollectionOption.TRUE and LazyCollectionOption.FALSE values are deprecated since you should be using the JPA FetchType attribute of the @OneToMany association.

您使用特定于休眠的方法来映射综合标识符.如休眠文档:

You use hibernate specific approach for mapping сomposite identifiers. As it's mentioned in the hibernate documentation:

必须由主键类(例如, @EmbeddedId @IdClass )表示复合标识符的限制只是JPA特定于.

The restriction that a composite identifier has to be represented by a primary key class (e.g. @EmbeddedId or @IdClass) is only JPA-specific.

Hibernate确实允许通过多个 @Id 属性在没有主键类的情况下定义复合标识符.

Hibernate does allow composite identifiers to be defined without a primary key class via multiple @Id attributes.

但是,如果您想实现更多的可移植性,则应该选择一种jpa允许的方法.

But if you want to achieve more portability you should prefer one of the jpa allowed approaches.

这篇关于为什么未在JPA中为插入语句分配值的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆