简体   繁体   English

在数据库上插入实体+外键的正确方法(使用:Mysql,JPA)

[英]Right way to make insertion of an entity + foreign key on database(Use : Mysql, JPA)

I have a question about the right way to make insertion of my entity + foreign key on database(MySQL, JPA).我有一个关于在数据库(MySQL,JPA)上插入我的实体 + 外键的正确方法的问题。 Before asking my question I tried solutions that I found, and I spent days to resolve the problem by myself.在问我的问题之前,我尝试了我找到的解决方案,我花了几天时间自己解决了这个问题。 I believe I have something wrong :我相信我有问题:

What I need to do is :我需要做的是:

  1. I have already data (informations) exists in Site table我已经在站点表中存在数据(信息)
  2. I have to make the insertion of new sequence in Sequence table我必须在序列表中插入新序列
  3. I have to make the insertion of new sequence in Sequence table, and association of FK site's (site exists and no need to inserting it again)我必须在序列表中插入新序列,以及 FK 站点的关联(站点存在且无需再次插入)

The main problem is :主要问题是:

  1. When I insert in Sequence Table I have Sequence with FK of Site inserted correctly当我在序列表中插入时,我有正确插入站点 FK 的序列
  2. BUT!但! The problem is I have also Site insertion in database, so redundant insertion of Site evry time I insert Sequence datas问题是我在数据库中也有站点插入,所以每次插入序列数据时都会冗余插入站点

I just need one insertion of Sequence with association (FK of Site). 我只需要插入一个带有关联的序列(站点的 FK)。

Below what's happen on my console : 下面是我的控制台上发生的事情:
@Override
        public Site findSiteByName(String Name_Site) {
            List sites = entityManager.createQuery("SELECT s FROM Site s").getResultList();
            for (Site item : sites) {
                if (item.getNom_Site().equals(Name_Site)) {
                    return item;
                }
            }
    
            return null;
        }


Jpa Repository : I first get Site object by name Jpa 存储库:我首先按名称获取站点对象

\n\n    @Override @覆盖\n        public Site findSiteByName(String Name_Site) {公共站点 findSiteByName(String Name_Site) {\n            List sites = entityManager.createQuery("SELECT s FROM Site s").getResultList(); List sites = entityManager.createQuery("SELECT s FROM Site s").getResultList();\n            for (Site item : sites) {对于(站点项目:站点){\n                if (item.getNom_Site().equals(Name_Site)) {如果 (item.getNom_Site().equals(Name_Site)) {\n                    return item;归还物品;\n                } }\n            } }\n    \n            return null;返回空;\n        } }\n\n

Jpa method to insert Sequence on data base 在数据库中插入序列的 Jpa 方法
@Entity
@Table(name = "Sequences")
public class Sequence {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "Id_Sequence", unique = true, nullable = false)
private long Id_Sequence;
private Date ....;
private Date ....;
private String ....;
private String ....;
private String ....;
private int ....;
private int ....;
private double ....;
private double ....;
@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
private Set<TraceSequence> traceSequences = new HashSet<>();
@ManyToOne(cascade = CascadeType.ALL)
private Site site;

public constructor...

public set..
public get..

My Rest controller : 我的休息控制器:
\n
@GET @Path("/addSeq") @Produces(MediaType.APPLICATION_JSON) @Consumes(MediaType.APPLICATION_JSON) public Sequence addSeq(@Context final UriInfo uriInfo) { Site site = siteService.findSiteByName("Name_Site"); Sequence sequence = sequenceFactory.CreateSequence(new Date(), new Date(), "", "", "", 4, 6, 10, 12); sequence.setSite(site); site.getSequences().add(sequence); sequenceservice.saveSequence(sequence); return null; }
\n

My principal classes are : 我的主要课程是:
\n
@Entity @Table(name = "Sequences") public class Sequence { @Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "Id_Sequence", unique = true, nullable = false) private long Id_Sequence; private Date ....; private Date ....; private String ....; private String ....; private String ....; private int ....; private int ....; private double ....; private double ....; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set<TraceSequence> traceSequences = new HashSet<>(); @ManyToOne(cascade = CascadeType.ALL) private Site site; public constructor... public set.. public get..
\n

\n   \n

@Entity @实体\n@Table(name = "Sites") @Table(name = "站点")\npublic class Site {公共类站点{

\n
@Id @GeneratedValue(strategy = GenerationType.AUTO) @Column(name = "Id_Site", unique = true, nullable = false) private long Id_Site; private String ...; private boolean ...; private long ...; private Date ...; private Date ...; private String ...; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set<Sequence> sequences = new HashSet<>(); @ManyToOne private ... ...; @OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER) private Set<...> ... = new HashSet<>(); @ManyToOne private ... ...; public constructor... public set.. public get..
\n

Could you try to remove the cascade = CascadeType.ALL in all of the relations?您可以尝试删除所有关系中的cascade = CascadeType.ALL吗? I think the main problem is that CascadeType.PERSIST is cascaded to the child elements.我认为主要问题是CascadeType.PERSIST级联到子元素。 You may have a look here JPA with JTA: Persist entity and merge cascaded child entities您可以在这里查看带有 JTA 的 JPA:持久实体和合并级联子实体

Another thing I would propose is to reduce your table count from 3 to 2. Since you are using a OneToMany -relation, which doesn't need a mapping table like you have now.我建议的另一件事是将表数从 3 减少到 2。由于您使用的是OneToMany关系,因此不需要像现在这样的映射表。 To achieve this a mappedBy-clause is used within the OneToMany-annotation and an additional JoinColumn-annotation on the ManyToOne site.为了实现这一点,在 OneToMany 注释中使用了一个 mappingBy 子句,并且在 ManyToOne 站点上使用了一个附加的 JoinColumn 注释。

@Entity
@Table(name = "Sites")
public class Site {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Id_Site", unique = true, nullable = false)
    private long Id_Site;
    private String ...;
    private boolean ...;
    private long ...; 
    private Date ...;
    private Date ...;
    private String ...;

    @OneToMany(mappedBy="site", fetch = FetchType.EAGER)
    private Set<Sequence> sequences = new HashSet<>();


@Entity
@Table(name = "Sequences")
public class Sequence {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "Id_Sequence", unique = true, nullable = false)
    private long Id_Sequence;
    private Date ....;
    private Date ....;
    private String ....;
    private String ....;
    private String ....;
    private int ....;
    private int ....;
    private double ....;
    private double ....;

    @OneToMany(fetch = FetchType.EAGER)
    private Set<Sequence> traceSequences = new HashSet<>();

    @ManyToOne(cascade = CascadeType.MERGE)
    @JoinColumn(name = "site_Id_Site", nullable = false)
    private Site site;

EDITED I tried with:编辑我试过:

public interface SequenceRepository extends JpaRepository<Sequence, Long> {

}

and

Site site = siteRepository.findOne(1L);

Sequence seq = new Sequence();
seq.setSite(site);
site.getSequences().add(seq);

sequenceRepository.save(seq);

brings带来

Hibernate: select site0_.id_site...
Hibernate: insert into sequences (site_id_site) values (?)

In classpath I do have spring-data-rest-webmvc-2.5.6.RELEASE.jar .在类路径中,我确实有spring-data-rest-webmvc-2.5.6.RELEASE.jar

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM