... and a reply-to-self again:
The issue with column privs is that Hibernate lists all columns, even ones it hasn't set or altered, in the INSERT and UPDATE statements it issues. Column privileges are checked based on the INSERT or UPDATE column list, not the actual values being changed, so even:
Code:
UPDATE test SET no_update_permission_column = no_update_permission_column;
... will fail, because permissions are checked before values are evaluated and compared. I didn't clearly explain that above, but that's why I wanted to alter the insertable= or updatable= settings on entity properties - to prevent the associated columns from being included in the INSERT or UPDATE list.
The reason Hibernate lists all columns in INSERT and UPDATE statements is that it pre-generates SQL for these operations and uses the same SQL for each operation, often as a prepared statement. To do so it must include all fields that may ever change. If you don't have permission to alter all those fields, they'll still be included in the SQL as Hibernate doesn't know that, so all operations will fail - even when you're only actually changing fields you're allowed to - since you're not allowed to even set columns you don't have permission for to their current values.
Two options exist: Either, at PU init time, rewrite the Hibernate mappings to include knowledge of user permissions,
or dynamically generate INSERT and UPDATE SQL to only include columns that have actually been set/changed.
The latter option may be achieved much more easily than the former. Hibernate supports generation of dynamic SQL for every individual UPDATE and INSERT, and must simply be told to use it. If you're using JPA2:
Code:
import javax.persistence.Entity;
import javax.persistence.Table;
@Entity
@Table(name = "myEntityTableName")
@org.hibernate.annotations.Entity(selectBeforeUpdate=true, dynamicInsert=true, dynamicUpdate=true)
class MyEntity {
// ....
};
It's much the same for XML mappings and for non-JPA Hibernate Annotations.
If you need crazy-fast INSERTs and UPDATEs on tables with column privs that vary based on logged-in role, you'll want to go through the hassle of modifying the mapping at PU creation time. Otherwise, just use dynamic SQL, (or make sure your column privs are set so that all Hibernate users have the same rights so you can set updatable= and insertable= statically in your mappings).