我正在使用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);”时到达后,将引发错误。