2

I have a User. That User has a Document. The Document has several Entries. If I delete a Document, then I would like to keep the children Entries, which will be orphans, for debugging purpose. Using the classes described at the bottom, when I delete a Document, I get a foreign key error:

Cannot delete or update a parent row: a foreign key constraint fails (relation.entry, CONSTRAINT FK4001852ED0B1AFE FOREIGN KEY (document_id) REFERENCES document (id))

I am using a framework that creates the tables based on the models. Using cascade = CascadeType.REMOVE makes it work but I do not want to remove the children. Is there a special CascadeType I should be using?

User

@Entity
public class User {
    public String name;

    @OneToOne(mappedBy = "user", cascade = CascadeType.ALL)
    public Document document;
}

Document

@Entity
public class Document {
    public String title;

    @OneToOne
    public User user;

    @OneToMany(mappedBy = "document")
    public List<Entry> entries;
}

Entry

@Entity
public class Entry {
    public String data;

    @ManyToOne
    public Document document;
}
4

2 回答 2

2

By default, JPA does not cascade any operations on a relationship such as the @ManyToOne relationship defined between Document and Entry. Since there is no cascade type defined in the mappings the cascading delete is most likely being performed by the database as specified by the foreign key constraint.

I suspect the error you are receiving originates in the database. Try changing the cascade operation performed in the database upon the deletion of a parent in the foreign key constraint. Many databases will allow you to set the foreign key to null. Here is an example for Oracle:

CONSTRAINT fk_column
     FOREIGN KEY (column1, column2, ... column_n)
     REFERENCES parent_table (column1, column2, ... column_n)
     ON DELETE SET NULL 

After performing a delete it would be important to perform a flush to realign the persistence context with the database.

于 2013-07-17T08:35:49.790 回答
0

After more testing I found out that if I did not have a bidirectional relationship between Document and Entry then no foreign key would be added in the database thus making the deletion leave the children be. If I added the CascadeType.REMOVE then it would also delete the children and not leave any orphans. This would however create a new table in the database, document_entry.

Updated Document

@Entity
public class Document {
    public String title;

    @OneToOne
    public User user;

    @OneToMany
    public List<Entry> entries;
}

Updated Entry

@Entity
public class Entry {
    public String data;
}
于 2013-07-17T12:28:09.847 回答