简体   繁体   中英

How to avoid foreign-key-constraint violations using pure JPA/Hibernate annotations

I'm working on a problem with my database-model for a while now. I use Hibernate to manage my entities and the whole thing is stored in a HSQLDB (In memory database) , so the tables are created at runtime by hibernate. A short example of my annotated classes looks like follows:

@Entity
@Table(name = "Paper")
public class Paper {
  @Id
  @Column(name = "ID")
  private Long id;

  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(name = "Paper_Ref", joinColumns = { @JoinColumn(name = "SrcID") }, inverseJoinColumns = { @JoinColumn(name = "DstID") })
  private Set<Paper> references = new HashSet<Paper>();
}

@Entity
@Table(name = "Paper_Ref")
public class PaperRef
{
  @Id
  private Long id;

  @Column(name = "SrcID")
  private Long srcId;

  @Column(name = "DstID")
  private Long dstId;
}

As you can see, one paper links to several other papers and the corresponding relation is stored in a table called Paper_Ref. SrcID and DstID have a foreign-key-nature to primary-key of Paper. But the addressed primary-keys don't necessarily exist in my database.

The whole thing works fine, but if there is some inconsistency in the data (eg adding a paper-reference before adding the corresponding papers) I get a foreign-key-constraint violation. Furthermore I'm not really able to control these inconsistencies manually because I receive the data from another source that doesn't have any constraints.

Usually that's how everybody would expect the relationship to work, but i'm searching for a way to avoid the violation or just ignore it. For example by manually removing the constraint.

My own workaround is to form a native query, that looks like:

SELECT p FROM Paper AS p WHERE p.id IN (SELECT pr.dstId FROM PaperRef pr WHERE srcId = :id)

But preferrably I want to use a native hibernate-solution where I can call the getter for my Set of papers, without using a selfmade query.

Is there any way to remove/disable the foreign-key constraint or another way to work around this beahviour? Or is it a misunderstanding of mine how the relations in hibernate work?

Thanks in advance!

I think I did now solve the problem. Thanks to all readers and contributors. HSQLDB provides an option to disable foreign-key-checks at runtime. The SQL-statement is as follows:

SET DATABASE REFERENTIAL INTEGRITY FALSE;

Turning off this feature has another consequence which is also noted in the HSQLDB Docs . Hibernate doesn't keep track of the changes made at the database anymore, so without further actions incomplete results are returned for the relationships (Subselects). To fix this, EntityManager.refresh() has to be called for every object that is probably detached!

I just use the in-memory database to get join-functionality, as the external service doesn't provide such a feature. I remove the entities afterwards, so it's not a big drawback for me.

Happy coding!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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