Java JPA强制插入相关实体(与更新相反)

Java JPA强制插入相关实体(与更新相反),java,hibernate,jpa,Java,Hibernate,Jpa,我想要的行为: Make ID | City | Vers 1 Jose S_5 MakeConfiguration MakeID | Something | Vers 1 nada S_5 当我得到这个实体(使用SpringDataJPA和一些定制的@Query)时,一切正常 当我尝试发布(完全相同的实体)时,我需要以下内容: Make ID | City | Vers 1 Jose

我想要的行为:

Make 
ID   |   City   |   Vers
1        Jose        S_5

MakeConfiguration
MakeID | Something | Vers
1         nada       S_5
当我得到这个实体(使用SpringDataJPA和一些定制的@Query)时,一切正常

当我尝试发布(完全相同的实体)时,我需要以下内容:

Make 
ID   |   City   |   Vers
1        Jose        S_5
1        Jose        S_6

MakeConfiguration
MakeID | Something | Vers
1         nada       S_5
1         nada       S_6
但我得到的是:

Make 
ID   |   City   |   Vers
1        Jose        S_5
1        Jose        S_6

MakeConfiguration
MakeID | Something | Vers
1         nada       S_6
(请注意,MakeConfiguration中没有创建新记录) 正在显示的SQL正在将一条新记录插入Make,并使用新版本更新MakeConfiguration中的记录。如果我修改了任何其他@Id注释值(在本例中是某些值),那么它将正确地插入一条新记录。hibernate似乎没有考虑版本上的@Id注释

我有以下内容(JPA/Hibernate实体)

@实体
@IdClass(MakeId.class)
公开课制作{
@身份证
@列(name=“MAKE_ID”)
私有字符串makeUuid;
@身份证
私人字符串城市
@Id@Column(name=“MAKE\u Id\u VERSION”)
@GeneratedValue(策略=GenerationType.SEQUENCE,generator=“version_seq”)
@通用生成器(
name=“version\u seq”,strategy=“com.me.VersionIdGenerator”
)
私有字符串makeIdVersion;
@OneToMany(fetch=FetchType.EAGER)
@列({
@JoinColumn(name=“clientProgramUuid”,referencedColumnName=“MAKE_ID”),
@JoinColumn(name=“clientUuidVersion”,referencedColumnName=“MAKE\u ID\u VERSION”)
})
私有列表生成配置;
}
@实体
@IdClass(MakeConfigurationId.class)
公共类生成配置{
@身份证
私有字符串makeConfigurationUuid
@身份证
私人字符串
@身份证
私有字符串makeIdVersion;
}
为了可读性,省略了IdClass、getter和setter。VersionIdgeGenerator按顺序生成下一个版本(比如S_1、S_2…S_N)

我也一直在打电话给entitymanager.Persiston生成实体


我已经尝试了几种方法来让它工作(双向的,等等),但没有运气。我认为我需要强制从Make生成的内容检索版本。

首先,不要使用Eager)使用
FetchType.LAZY

第二,不要经常使用
@id
。每个实体仅使用一次<代码>@Id:此注释指定实体的主键。即使您在某个对象的列id中放置,也只需使用
@column

顺便说一句,图书馆(适用于Maven):


org.projectlombok
龙目
真的
我修正了你的程序。应该是这样的:

导入lombok.allargsconstuctor;
导入龙目数据;
导入lombok.noargsconstuctor;
导入javax.persistence.*;
导入java.util.ArrayList;
导入java.util.List;
@资料
@AllArgsConstructor
@诺尔格构装师
@桌子
@实体
公开课制作{
@身份证
@列(name=“ID”)
@GeneratedValue(策略=GenerationType.SEQUENCE,generator=“版本\生成器”)
@SequenceGenerator(name=“version\u generator”,sequenceName=“seq\u version”,allocationSize=1)
私人长id;
@纵队
私有字符串makeUuid;
@纵队
私人城市;
@独身癖(
级联={
CascadeType.MERGE,
级联型
},fetch=FetchType.LAZY
)
私有列表makeConfigurations=new ArrayList();
public void addMakeConfigurations(MakeConfiguration MakeConfiguration){
添加(makeConfiguration);
}
public void removeMakeConfigurations(MakeConfiguration MakeConfiguration){
makeConfigurations.remove(makeConfiguration);
}
}
@资料
@AllArgsConstructor
@诺尔格构装师
@桌子
@实体
公共类生成配置{
@身份证
@列(name=“ID”)
@GeneratedValue(策略=GenerationType.SEQUENCE,generator=“makeConfig_generator”)
@SequenceGenerator(name=“makeConfig\u generator”,sequenceName=“seq\u makeConfig”,allocationSize=1)
私人长id;
@纵队
私有字符串makeConfigurationUuid;
@纵队
私人串东西;
@纵队
私有字符串版本;
}

看起来您的交易有问题。。。您是否获取版本
5\u 5
MakeConfiguration
并对其进行修改?如果是:这是否都发生在一个事务中?如果是:实体仍被附加,因此会被更新。如果您使用
@Transactional(propagation=propagation.REQUIRES_NEW)
注释获取
MakeConfiguration
的方法,这可能是可以避免的。不,我唯一的交互是通过rest API(get+post)进行的,因此不应该附加任何内容。这里似乎存在误解。。。在应用程序中,您需要一些代码(可能是
存储库
)与数据库交互。一定涉及到一些交易。无事务=无数据库交互。
@Entity
@IdClass(MakeId.class)
public class Make {
    @Id
    @Column(name="MAKE_ID")
    private String makeUuid;

    @Id
    private String city

    @Id @Column(name = "MAKE_ID_VERSION")
    @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "version_seq")
    @GenericGenerator(
            name = "version_seq", strategy = "com.me.VersionIdGenerator"
    )
    private String makeIdVersion;

    @OneToMany(fetch = FetchType.EAGER)
    @JoinColumns( {
            @JoinColumn(name = "clientProgramUuid", referencedColumnName = "MAKE_ID"),
            @JoinColumn(name = "clientUuidVersion", referencedColumnName = "MAKE_ID_VERSION")
    })
    private List<MakeConfiguration> makeConfigurations;
}

@Entity
@IdClass(MakeConfigurationId.class)
public class MakeConfiguration {
    @Id
    private String makeConfigurationUuid

    @Id
    private String something

    @Id
    private String makeIdVersion;
}
<dependency>
    <groupId>org.projectlombok</groupId>
    <artifactId>lombok</artifactId>
    <optional>true</optional>
</dependency>