- 
                Notifications
    You must be signed in to change notification settings 
- Fork 234
Open
Description
Hello, we are having some trouble with the FilterExpressionCheck. When we are doing a Post operation to create a new entity that holds 2 non-null ManyToOne relationships that were previously created, and the call is intercepted by a ReadPermission with a FilterExpressionCheck we got a 500 error with this error:
not-null property references a null or transient value: org.example.permission.permissions.domain.Books.store
	at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:112) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.internal.Nullability.checkNullability(Nullability.java:57) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.action.internal.AbstractEntityInsertAction.nullifyTransientReferencesIfNotAlready(AbstractEntityInsertAction.java:126) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.action.internal.EntityIdentityInsertAction.execute(EntityIdentityInsertAction.java:73) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:682) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction(ActionQueue.java:293) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.spi.ActionQueue.addInsertAction(ActionQueue.java:274) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.spi.ActionQueue.addAction(ActionQueue.java:324) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction(AbstractSaveEventListener.java:394) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate(AbstractSaveEventListener.java:308) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.AbstractSaveEventListener.performSave(AbstractSaveEventListener.java:224) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId(AbstractSaveEventListener.java:136) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient(DefaultPersistEventListener.java:177) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.DefaultPersistEventListener.persist(DefaultPersistEventListener.java:95) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:79) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:138) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:825) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.spi.CascadingActions$8.cascade(CascadingActions.java:338) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.spi.CascadingActions$8.cascade(CascadingActions.java:328) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:570) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:492) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:253) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:604) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:534) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:495) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:253) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:192) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:193) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:158) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.AbstractFlushingEventListener.preFlush(AbstractFlushingEventListener.java:107) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoPreFlush(DefaultAutoFlushEventListener.java:104) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.event.service.internal.EventListenerGroupImpl.fireEventOnEachListener(EventListenerGroupImpl.java:127) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.internal.SessionImpl.autoPreFlush(SessionImpl.java:1391) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.withCacheableSqmInterpretation(ConcreteSqmSelectQueryPlan.java:382) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.query.sqm.internal.ConcreteSqmSelectQueryPlan.performScroll(ConcreteSqmSelectQueryPlan.java:370) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.query.sqm.internal.QuerySqmImpl.doScroll(QuerySqmImpl.java:456) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.query.spi.AbstractSelectionQuery.scroll(AbstractSelectionQuery.java:242) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.query.spi.AbstractSelectionQuery.stream(AbstractSelectionQuery.java:259) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at org.hibernate.query.spi.AbstractSelectionQuery.getResultStream(AbstractSelectionQuery.java:253) ~[hibernate-core-6.6.18.Final.jar:6.6.18.Final]
	at com.yahoo.elide.datastores.jpa.porting.QueryWrapper.scroll(QueryWrapper.java:61) ~[elide-datastore-jpa-7.1.11.jar:na]
	at com.yahoo.elide.datastores.jpql.JPQLTransaction.lambda$loadObjects$1(JPQLTransaction.java:156) ~[elide-datastore-hibernate-7.1.11.jar:na]
	at com.yahoo.elide.core.utils.TimedFunction.get(TimedFunction.java:33) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.datastores.jpql.JPQLTransaction.loadObjects(JPQLTransaction.java:157) ~[elide-datastore-hibernate-7.1.11.jar:na]
	at com.yahoo.elide.core.datastore.inmemory.InMemoryStoreTransaction.lambda$loadObjects$2(InMemoryStoreTransaction.java:120) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.core.datastore.inmemory.InMemoryStoreTransaction.fetchData(InMemoryStoreTransaction.java:265) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.core.datastore.inmemory.InMemoryStoreTransaction.loadObjects(InMemoryStoreTransaction.java:126) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.core.datastore.DataStoreTransaction.loadObject(DataStoreTransaction.java:148) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.core.datastore.inmemory.InMemoryStoreTransaction.loadObject(InMemoryStoreTransaction.java:112) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.core.PersistentResource.loadRecord(PersistentResource.java:281) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.models.Resource.toPersistentResource(Resource.java:187) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.models.Relationship.toPersistentResources(Relationship.java:81) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.parser.state.CollectionTerminalState.createObject(CollectionTerminalState.java:243) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.parser.state.CollectionTerminalState.handlePost(CollectionTerminalState.java:141) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.parser.state.StateContext.handlePost(StateContext.java:116) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.parser.PostVisitor.visitQuery(PostVisitor.java:31) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.parser.PostVisitor.visitQuery(PostVisitor.java:18) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.generated.parsers.CoreParser$QueryContext.accept(CoreParser.java:582) ~[elide-core-7.1.11.jar:na]
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visitChildren(AbstractParseTreeVisitor.java:46) ~[antlr4-runtime-4.13.1.jar:4.13.1]
	at com.yahoo.elide.generated.parsers.CoreBaseVisitor.visitStart(CoreBaseVisitor.java:21) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.parser.BaseVisitor.visitStart(BaseVisitor.java:47) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.parser.BaseVisitor.visitStart(BaseVisitor.java:33) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.generated.parsers.CoreParser$StartContext.accept(CoreParser.java:118) ~[elide-core-7.1.11.jar:na]
	at org.antlr.v4.runtime.tree.AbstractParseTreeVisitor.visit(AbstractParseTreeVisitor.java:18) ~[antlr4-runtime-4.13.1.jar:4.13.1]
	at com.yahoo.elide.jsonapi.JsonApi.visit(JsonApi.java:251) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.JsonApi.lambda$post$1(JsonApi.java:137) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.JsonApi.handleRequest(JsonApi.java:276) ~[elide-core-7.1.11.jar:na]
	at com.yahoo.elide.jsonapi.JsonApi.post(JsonApi.java:129) ~[elide-core-7.1.11.jar:na]
Steps to reproduce
- Create an Author Entity that has a @ReadPermission implemented with FilterExpressionCheck ✅
- Create a Store Entity that has a @ReadPermission implemented with FilterExpressionCheck ✅
- Create a Book Entity that has a relationship with the previously created Author and Store ❌
We are using a FilterExpressionCheck to filter out values from Read responses that do not conform to an header passed in the request;
Moreover, we cannot use the OperationCheck because we need the Read response to be paginated.
To reproduce this error, I've created a small repo with the bare minimum implementation:
PermissionTest
Below here the API calls to reproduce the issue
1.Author:
 curl --location 'http://localhost:8087/permission/author' \
--header 'X-Code-Permission: code-1' \
--header 'Content-Type: application/vnd.api+json' \
--data '{
    "data": {
        "type": "author",
        "attributes": {
            "code": "code-1"
        }
    }
}'
- Store:
curl --location 'http://localhost:8087/permission/store' \
--header 'X-Code-Permission: code-1' \
--header 'Content-Type: application/vnd.api+json' \
--data '{
    "data": {
        "type": "store",
        "attributes": {
            "code": "code-1",
            "name": "name"
        }
    }
}'
- Books:
curl --location 'http://localhost:8087/permission/books' \
--header 'X-Code-Permission: code-1' \
--header 'Content-Type: application/vnd.api+json' \
--data '{
    "data": {
        "type": "books",
        "attributes": {
            "code": "code-1"
        },
        "relationships": {
            "author": {
                "data": {
                    "type": "author",
                    "id": "1"
                }
            },
            "store": {
                "data": {
                    "type": "store",
                    "id": "1"
                }
            }
        }
    }
}'
Let me know if more information are needed.
Metadata
Metadata
Assignees
Labels
No labels