1 year ago
#82716
abdul mannan
Stackoverflow error when trying to delete parent entity using hibernate
I am using hibernate to check if it can be used for all operations I want to be able to do in my application. So this is a PoC stage that I am in right now.
The following is my persistence-mappings-asset.xml file:
<hibernate-mapping>
<class entity-name="Asset">
<id name="id"
type="long"
column="ID">
<generator class="increment"/>
</id>
<property name="name"
column="NAME"
type="string"/>
<set name="assetspec"
inverse="true"
lazy="true"
cascade="all,delete-orphan"
>
<key column="asset_id"/>
<one-to-many entity-name="Assetspec"/>
</set>
</class>
<class entity-name="Assetspec">
<!-- uuid may be used for generator -->
<id name="id"
type="long"
column="ID">
<generator class="increment"/>
</id>
<property name="attributeid"
column="attributeid"
type="string"/>
<property name="description"
column="description"
type="string"/>
<property name="alnvalue"
column="alnvalue"
type="string"/>
<property name="numvalue"
column="numvalue"
type="string"/>
<many-to-one name="asset"
column="asset_id"
entity-name="Asset"
update="true"/>
</class>
</hibernate-mapping>
When I delete an Asset object, I want all of its associated child entities to also be deleted. I have tried 2 ways and both of them yield a different error.
package com.layerexchange.ams.persistence;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.transform.ResultTransformer;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import java.io.FileOutputStream;
import java.io.PrintStream;
import java.util.*;
import javax.persistence.Query;
@SpringBootApplication
@RequiredArgsConstructor
@Slf4j
public class PersistencePocApplication implements CommandLineRunner {
public static void main(String[] args) {
SpringApplication.run(PersistencePocApplication.class, args);
}
private final SessionFactory sessionFactory;
@Override
public void run(String... args) throws Exception {
Session session = sessionFactory.openSession();
Transaction transaction = session.beginTransaction();
// we intialise with 2 diff Asset entities and 4 diff AssetSpec entities
Map asset1 = new HashMap<>();
Map asset2 = new HashMap<>();
Map asset3 = new HashMap<>();
asset1.put("name", "asset 1");
asset2.put("name", "asset 2");
asset3.put("name", "asset 3");
session.save("Asset", asset1);
session.save("Asset", asset2);
session.save("Asset", asset3);
Map assetSpec1 = new HashMap<>();
Map assetSpec2 = new HashMap<>();
Map assetSpec3 = new HashMap<>();
Map assetSpec4 = new HashMap<>();
assetSpec1.put("attributeid", "a101");
assetSpec2.put("attributeid", "a102");
assetSpec3.put("attributeid", "a103");
assetSpec4.put("attributeid", "a104");
assetSpec1.put("description", "This is asset spec 1 with attribute id a101");
assetSpec2.put("description", "This is asset spec 2 with attribute id a102");
assetSpec3.put("description", "This is asset spec 3 with attribute id a103");
assetSpec4.put("description", "This is asset spec 4 with attribute id a104");
assetSpec1.put("alnvalue", "b101");
assetSpec2.put("alnvalue", "b102");
assetSpec3.put("alnvalue", "b103");
assetSpec4.put("alnvalue", "b104");
assetSpec1.put("numvalue", "1");
assetSpec2.put("numvalue", "2");
assetSpec3.put("numvalue", "3");
assetSpec4.put("numvalue", "4");
assetSpec1.put("asset", asset1);
assetSpec2.put("asset", asset2);
assetSpec3.put("asset", asset1);
assetSpec4.put("asset", asset2);
session.save("Assetspec", assetSpec1);
session.save("Assetspec", assetSpec2);
session.save("Assetspec", assetSpec3);
session.save("Assetspec", assetSpec4);
transaction.commit();
session.close();
// testing crud operations and how they affect the child entities
session = sessionFactory.openSession();
transaction = session.beginTransaction();
// test for deleting parent, and checking if child entities of it are also
// deleted
// Option 1
Long id = (long) 2;
Map asset1item = (Map) session.get("Asset", id);
session.delete(asset1item);
// Option 2
Query q = session.createQuery("delete Asset where id = 2");
q.executeUpdate();
transaction.commit();
session.close();
}
}
When I try Option 1, I get a java.lang.StackOverflowError: null error. I assume this is because hibernate executes the following query hundreds of times:
Hibernate: select assetspec0_.asset_id as asset_id6_1_0_, assetspec0_.id as id1_1_0_, assetspec0_.id as id1_1_1_, assetspec0_.attributeid as attribut2_1_1_, assetspec0_.description as descript3_1_1_, assetspec0_.alnvalue as alnvalue4_1_1_, assetspec0_.numvalue as numvalue5_1_1_, assetspec0_.asset_id as asset_id6_1_1_ from assetspec assetspec0_ where assetspec0_.asset_id=?
When I try Option 2, I get the following error:
Caused by: org.h2.jdbc.JdbcSQLIntegrityConstraintViolationException: Referential integrity constraint violation: "FKS0VRHCNJ2NBHKWLIN7GL8COTK: PUBLIC.ASSETSPEC FOREIGN KEY(ASSET_ID) REFERENCES PUBLIC.ASSET(ID) (2)"; SQL statement:
delete from asset where id=2 [23503-200]
I know that this operation should be possible but I have no idea where I may be going wrong so any help would be greatly appreciated.
spring
spring-boot
hibernate
spring-data-jpa
nhibernate-mapping
0 Answers
Your Answer