1

I'm using hibernate-types-52 by Vlad Mihalcea together with Spring JPA to insert a POJO as a Json value into my Postgresql database.

My entity is defined this way:

@Entity
@Table(name = "hoshin_kanri")
@TypeDef(
        name = "jsonb",
        typeClass = JsonBinaryType.class
)
public class HKEntity {

    @Id
    @Column(name = "id_ai", columnDefinition = "bigint")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id_ai;

    @Column(name = "id_hk", columnDefinition = "bigint")
    private Integer id_hk;

    @Type(type = "jsonb")
    @Column(name = "hk_data", columnDefinition = "jsonb")
    private HKData hk_data;

    public HKEntity(Integer id_hk, HKData hk_data) {
        this.id_hk = id_hk;
        this.hk_data = hk_data;
    }

And this is the POJO:

public class HKData {
    private String name;
    private Year targetYear;
    private String description;

    public HKData(String name, Year targetYear, String description) {
        this.name = name;
        this.targetYear = targetYear;
        this.description = description;
    }

I've defined a Repository interface to query the objects into the database:

public interface HKRepository extends CrudRepository<HKEntity, Integer> {

    @Query(value = "INSERT INTO 'hk_data' VALUES :Entity", nativeQuery = true)
    void test_json(@Param("Entity") HKEntity e);
}

and a test Service just to see if it's working properly:

@Service
public class HKService {

    @Autowired
    HKRepository hk_repository;

    public String json_test() {
        HKData d = new HKData("Prova", Year.now(), "Descrizione");
        HKEntity e = new HKEntity(1,d);
        hk_repository.test_json(e);
        return "Value created";
    }
}

However, i keep getting the following exception:

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: com.ehk.rest.entity.HKEntity

I've tried many fixes suggested for this error, but i cannot understand the nature of the error itself. What is wrong with this approach? Beside a tip for fixing this, i would like to understand why this error is originated.

1 Answer 1

1

The error means that there's an instance of the HKEntity entity which is referenced from somewhere in the current Hibernate session, and you've neither explicitly persisted this instance, nor instructed Hibernate to persist it cascadly. It's hard to say what exactly is going on, but there are some issues with your code that might have confused either Spring Data JPA framework, or the Hibernate itself.

First, the Spring's CrudRepository interface already has a save() method, so you could use it instead of your test_json() method.

I also see no reason in inserting a Hibernate entity with a native query, and I don't even think this is a valid query. Your test_json() method tries to natively insert an HKEntity entity into the hk_data table, but the HKEntity entity should be saved into the hoshin_kanri table, according to your mapping.

So I would change your service code as follows:

    public String json_test() {
        HKData d = new HKData("Prova", Year.now(), "Descrizione");
        HKEntity e = new HKEntity(1,d);
        hk_repository.save(e);
        return "Value created";
    }
Sign up to request clarification or add additional context in comments.

4 Comments

Thanks for the clarification. I will give it a try now: as for the hoshin_kanri table, i corrected that mistake but i was getting the same error. The generated values however is just for the id_ai, while the id_hk is something that i can assign (that's the reason why i gave it a random number of my choice, it is not a primary key and the value can be duplicate)
I tried to use the save() method from the CrudRepository interface and no other changes (except the above mentioned correction of the table name) and it works just fine. I suppose the mistake was my native query. Meanwhile, thanks again for the support. The solution was to use the save method instead of defining an insert query myself (At this point though, i wonder how to execute custom queries without having this kind of problem)
Oh, I didn't notice that the first argument of the constructor was id_hk, not id_ai value. I'm glad that my answer was helpful. You can write both custom Hibernate queries in HQL language, and custom native queries in SQL language, but the syntax would be different - the HQL queries operate on objects, the native SQL queries operate on tables and fields. So you need to distinguish between the two. In your case, you've used an object in a native query, which is usually not what you want.
It is really clear now, and it was extremely helpful to understand better how it works! So thank you a lot again for your support and time. I will try with other types of queries as soon as i proceed with the development

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.