1
votes

Thera are oracle view vendor_view and table vendors (vendors table contains only PK with name id for simplicity)

create view vendor_view as
    select id as vid, 'YES' as active
    from vendors;

Coresponding entity

@Entity
@Table(name = "vendors")
@SecondaryTable(name = "vendor_view", pkJoinColumns = {@PrimaryKeyJoinColumn(name = "vid", referencedColumnName = "id")})
public class Vendor {

    @Id
    private Long id;

    @Column(table = "vendor_view", name = "vid", insertable = false, updatable = false)
    private Long vid;

    @Column(table = "vendor_view", name = "active", insertable = false, updatable = false)
    private String active;


     getter and setter....
}

When i try to persist new Vendor entity then face with issue:

org.springframework.dao.InvalidDataAccessResourceUsageException: could not prepare statement; SQL [insert into vendor_view (vid) values (?)]; nested exception is org.hibernate.exception.SQLGrammarException: could not prepare statement
            at org.springframework.orm.jpa.vendor.HibernateJpaDialect.convertHibernateAccessException(HibernateJpaDialect.java:238)
.....
Caused by: org.hsqldb.HsqlException: INSERT, UPDATE, DELETE or TRUNCATE not permitted for table or view
            at org.hsqldb.error.Error.error(Unknown Source)

JPA Implementation is Hibirnate.
Question is why Hibirnate generate insert query for field that mark as insertable = false, updatable = false ?

2
See my answer here stackoverflow.com/a/37160701/1356423. Unless you are explicitly setting one of the fields mapped to the @SecondaryTable (which you shouldn't be if it is a view) then no insert update statement is executed. If you are then an insert statement will be made for ID column even if all other fields are mapped an non-insertable/updateable.Alan Hay

2 Answers

0
votes

As hibernate doesn't know whether the table you are trying to insert is a table or a view until and unless it interacts with the database. So it is runtime exception which can be checked only when Java program interacts with Database.

It is similar to even if table doesn't exist it will make query but on runtime it will throw exception.

0
votes

You would do that when the responsibility of creating/udpating the related entity in question isn't in the current entity. E.g. you have a Person and an Address. You'd like to add insertable=false, updatable=false to the @OneToMany relationship with the Person entity in the Address entity, simply because it's not the responsibility of the Address entity to create or update a Person. It's the other way round. This is not really a technical, but more a semantic/natural decision.