如何使用现有对象持久化对象树

时间:2018-06-26 23:12:08

标签: java jpa java-ee

我正在使用EclipeLink(JPA),并且试图解析一个Docoment以频繁地导入包含的数据。我们的软件体系结构的构建方式是,我将获得代表对象树的根元素列表,并且这些元素可能已经在数据库中可用,因为它们可以不带父项而存在!

我的DataModel看起来像这样:

@Entity
@Table(name = "studiengang")
public class Studiengang
{
   @Id
   @GeneratedValue(strategy = GenerationType.IDENTITY)
   @Column(name = "id", length = 5)
   private int id;

   @Column(name = "name", length = 50, nullable = false, unique = true)
   private String name;

   @ManyToMany(mappedBy = "studiengaenge", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
   private Set<Vorlesung> vorlesungen;
   //getter + setter
}



@Entity
@Table(name = "vorlesung")
public class Vorlesung
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", length = 5)
    private int id;

    @Column(name = "name", length = 50, nullable = false, unique = true)
    private String name;

    @ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
    private Set<Studiengang> studiengaenge;

    @ManyToMany(mappedBy = "vorlesungen", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
    private Set<KfzKennzeichen> kennzeichen;

    @OneToMany(mappedBy = "vorlesung", fetch = FetchType.EAGER, cascade = CascadeType.MERGE)
    private Set<Veranstaltung> veranstaltungen;
}




@Entity
@Table(name = "veranstaltung", uniqueConstraints = {
    @UniqueConstraint(columnNames = { "von", "bis", "vorlesung" })
})
public class Veranstaltung
{
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id", length = 5)
    private int id;

    @ManyToOne(fetch = FetchType.EAGER, optional = false, cascade = CascadeType.MERGE)
    private Vorlesung vorlesung;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    private Date von;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(nullable = false)
    private Date bis;

    @ManyToOne(fetch = FetchType.EAGER, optional = false, cascade = CascadeType.MERGE)
    private Raum veranstaltungsOrt;
 }



 @Entity
 @Table(name = "raum")
 public class Raum
 {
     @Id
     @GeneratedValue(strategy = GenerationType.IDENTITY)
     @Column(name = "id", length = 5)
     private int id;

     @Column(name = "name", length = 15, nullable = false, unique = true)
     private String name;

     @OneToMany(mappedBy = "veranstaltungsOrt", fetch = FetchType.EAGER)
     private Set<Veranstaltung> veranstaltungen;
 }

我现在得到的是一个Studiengang类型的列表,我想(最好)轻松地保留它。如您所见,我已经尝试将所有内容标记为Cascade Merge,但这并没有帮助。

我最喜欢的方法是只正确配置一些实体,然后调用:

public void importiereVorlesungen(List<Studiengang> studiengaenge)
{
    for (Studiengang studiengang : studiengaenge)
    {
        persistiereEntitaet(studiengang);
    }
}

private <T> T persistiereEntitaet(T entitaet)
{
    T dbEntitaet;
    em.getTransaction().begin();
    dbEntitaet = em.merge(entitaet);
    em.getTransaction().commit();

    return dbEntitaet;
}

但这暂时不起作用。尽管我合并了实体,但出现了错误:

  

原因:java.sql.SQLIntegrityConstraintViolationException:键“名称”的条目“ S 1”重复       在com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:115)       在com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:95)       在com.mysql.cj.jdbc.exceptions.SQLExceptionsMapping.translateException(SQLExceptionsMapping.java:122)       在com.mysql.cj.jdbc.ClientPreparedStatement.executeInternal(ClientPreparedStatement.java:960)       在com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1116)       在com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdateInternal(ClientPreparedStatement.java:1066)       在com.mysql.cj.jdbc.ClientPreparedStatement.executeLargeUpdate(ClientPreparedStatement.java:1396)       在com.mysql.cj.jdbc.ClientPreparedStatement.executeUpdate(ClientPreparedStatement.java:1051)       在org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:890)       ...还有74个

即使我尝试这样做,也会收到相同的错误:

for (Studiengang studiengang : studiengaenge)
{ 
    for (Vorlesung vorlesung : studiengang.getVorlesungen())
    {
        for (Veranstaltung veranstaltung : vorlesung.getVeranstaltungen())
        {
            Raum dbRaum;
            try
                {
                    dbRaum = persistiereEntitaet(veranstaltung.getVeranstaltungsOrt());
                }
                catch (Exception e)
                {
                    dbRaum = sucheRaum(veranstaltung.getVeranstaltungsOrt().getName());
                }
                veranstaltung.setVeranstaltungsOrt(dbRaum);
                persistiereEntitaet(veranstaltung);
            }
            try
            {
                persistiereEntitaet(vorlesung);
            }
            catch (DatabaseException e)
            {
                //Skip
            }
        }
        em.getTransaction().begin();
        em.persist(studiengang);
        em.getTransaction().commit();
        }
    }
}

当行“ persistiereEntitaet(veranstaltung);”时到达后,将引发错误。

0 个答案:

没有答案