diff --git a/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/DocumentResource.java b/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/DocumentResource.java index c04920ab3e..25314847a5 100644 --- a/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/DocumentResource.java +++ b/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/DocumentResource.java @@ -21,6 +21,7 @@ import com.blazebit.persistence.examples.quarkus.base.entity.Document; import com.blazebit.persistence.examples.quarkus.base.view.DocumentUpdateView; import com.blazebit.persistence.examples.quarkus.base.view.DocumentView; +import com.blazebit.persistence.examples.quarkus.base.view.DocumentWithJsonIgnoredNameView; import com.blazebit.persistence.integration.jaxrs.EntityViewId; import com.blazebit.persistence.view.EntityViewManager; import com.blazebit.persistence.view.EntityViewSetting; @@ -29,6 +30,7 @@ import javax.persistence.EntityManager; import javax.transaction.Transactional; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.GET; import javax.ws.rs.POST; import javax.ws.rs.PUT; @@ -48,11 +50,11 @@ public class DocumentResource { @Inject - EntityManager em; + private EntityManager em; @Inject - EntityViewManager evm; + private EntityViewManager evm; @Inject - CriteriaBuilderFactory cbf; + private CriteriaBuilderFactory cbf; @Transactional @PUT @@ -80,4 +82,19 @@ public List getDocuments(@QueryParam("age") List ages) { CriteriaBuilder cb = cbf.create(em, Document.class).where("age").in().fromValues(Long.class, "age", ages).end(); return evm.applySetting(EntityViewSetting.create(DocumentView.class), cb).getResultList(); } + + @GET + @Transactional + @Produces("application/vnd.blazebit.noname+json") + public List getDocumentsWithJsonIgnoredName(@QueryParam("age") List ages) { + CriteriaBuilder cb = cbf.create(em, Document.class).where("age").in().fromValues(Long.class, "age", ages).end(); + return evm.applySetting(EntityViewSetting.create(DocumentWithJsonIgnoredNameView.class), cb).getResultList(); + } + + @DELETE + @Transactional + public Response clearDocuments() { + cbf.delete(em, Document.class).executeUpdate(); + return Response.ok().build(); + } } diff --git a/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/DocumentTypeResource.java b/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/DocumentTypeResource.java index 9c4d635489..908a1d23cb 100644 --- a/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/DocumentTypeResource.java +++ b/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/DocumentTypeResource.java @@ -15,6 +15,8 @@ */ package com.blazebit.persistence.examples.quarkus.base.resource; +import com.blazebit.persistence.CriteriaBuilderFactory; +import com.blazebit.persistence.examples.quarkus.base.entity.DocumentType; import com.blazebit.persistence.examples.quarkus.base.view.DocumentTypeCreateView; import com.blazebit.persistence.examples.quarkus.base.view.DocumentTypeUpdateView; import com.blazebit.persistence.examples.quarkus.base.view.DocumentTypeView; @@ -25,6 +27,7 @@ import javax.persistence.EntityManager; import javax.transaction.Transactional; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; @@ -41,9 +44,11 @@ public class DocumentTypeResource { @Inject - EntityManager em; + private EntityManager em; @Inject - EntityViewManager evm; + private EntityViewManager evm; + @Inject + private CriteriaBuilderFactory cbf; @Transactional @POST @@ -63,4 +68,11 @@ public DocumentTypeView updateDocumentType(@EntityViewId("id") DocumentTypeUpdat evm.save(em, documentTypeUpdateView); return evm.find(em, DocumentTypeView.class, documentTypeUpdateView.getId()); } + + @DELETE + @Transactional + public Response clearDocumentTypes() { + cbf.delete(em, DocumentType.class).executeUpdate(); + return Response.ok().build(); + } } diff --git a/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/PersonResource.java b/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/PersonResource.java index 372ca0ce64..511005b372 100644 --- a/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/PersonResource.java +++ b/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/resource/PersonResource.java @@ -16,6 +16,8 @@ package com.blazebit.persistence.examples.quarkus.base.resource; +import com.blazebit.persistence.CriteriaBuilderFactory; +import com.blazebit.persistence.examples.quarkus.base.entity.Person; import com.blazebit.persistence.examples.quarkus.base.view.PersonCreateView; import com.blazebit.persistence.examples.quarkus.base.view.PersonUpdateView; import com.blazebit.persistence.examples.quarkus.base.view.PersonView; @@ -26,6 +28,7 @@ import javax.persistence.EntityManager; import javax.transaction.Transactional; import javax.ws.rs.Consumes; +import javax.ws.rs.DELETE; import javax.ws.rs.POST; import javax.ws.rs.PUT; import javax.ws.rs.Path; @@ -42,9 +45,11 @@ public class PersonResource { @Inject - EntityManager em; + private EntityManager em; @Inject - EntityViewManager evm; + private EntityViewManager evm; + @Inject + private CriteriaBuilderFactory cbf; @Transactional @PUT @@ -63,4 +68,11 @@ public Response addPerson(PersonCreateView view) { evm.save(em, view); return Response.created(URI.create("/persons/" + view.getId())).build(); } + + @DELETE + @Transactional + public Response clearPersons() { + cbf.delete(em, Person.class).executeUpdate(); + return Response.ok().build(); + } } diff --git a/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/view/DocumentWithJsonIgnoredNameView.java b/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/view/DocumentWithJsonIgnoredNameView.java new file mode 100644 index 0000000000..af673ebf15 --- /dev/null +++ b/examples/quarkus/base/src/main/java/com/blazebit/persistence/examples/quarkus/base/view/DocumentWithJsonIgnoredNameView.java @@ -0,0 +1,32 @@ +/* + * Copyright 2014 - 2020 Blazebit. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package com.blazebit.persistence.examples.quarkus.base.view; + +import com.blazebit.persistence.examples.quarkus.base.entity.Document; +import com.blazebit.persistence.view.EntityView; +import com.fasterxml.jackson.annotation.JsonIgnore; + +/** + * @author Moritz Becker + * @since 1.5.0 + */ +@EntityView(Document.class) +public interface DocumentWithJsonIgnoredNameView extends DocumentView { + + @JsonIgnore + String getName(); +} diff --git a/examples/quarkus/testsuite/base/src/main/java/com/blazebit/persistence/examples/quarkus/testsuite/base/AbstractQuarkusExampleTest.java b/examples/quarkus/testsuite/base/src/main/java/com/blazebit/persistence/examples/quarkus/testsuite/base/AbstractQuarkusExampleTest.java index 1496490fae..da8cb7b52c 100644 --- a/examples/quarkus/testsuite/base/src/main/java/com/blazebit/persistence/examples/quarkus/testsuite/base/AbstractQuarkusExampleTest.java +++ b/examples/quarkus/testsuite/base/src/main/java/com/blazebit/persistence/examples/quarkus/testsuite/base/AbstractQuarkusExampleTest.java @@ -17,14 +17,19 @@ import io.quarkus.test.common.http.TestHTTPResource; import io.restassured.http.ContentType; +import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; +import javax.ws.rs.core.HttpHeaders; +import javax.ws.rs.core.MediaType; import java.net.URI; +import java.util.Map; import java.util.UUID; import static io.restassured.RestAssured.given; import static org.hamcrest.Matchers.matchesPattern; import static org.hamcrest.core.Is.is; +import static org.junit.jupiter.api.Assertions.assertFalse; /** * @author Moritz Becker @@ -35,6 +40,13 @@ public abstract class AbstractQuarkusExampleTest { @TestHTTPResource protected URI apiBaseUri; + @AfterEach + public void clearData() { + given().when().delete("/documents"); + given().when().delete("/document-types"); + given().when().delete("/persons"); + } + @Test public void createDocument() { given() @@ -58,12 +70,35 @@ public void getDocuments() { given() .queryParam("age", 1) + .header(HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON) .when().get("/documents") .then() .statusCode(200) .body("size()", is(1)); } + @Test + public void getDocumentsWithJsonIgnoredName() { + given() + .body("{\"name\": \"Doc1\", \"age\": 1}") + .contentType(ContentType.JSON) + .when().post("/documents") + .then() + .statusCode(201) + .header("Location", matchesPattern("http://localhost:" + apiBaseUri.getPort() + "/documents/.*")); + + Map document = given() + .queryParam("age", 1) + .header(HttpHeaders.ACCEPT, "application/vnd.blazebit.noname+json") + .when().get("/documents") + .then() + .statusCode(200) + .body("size()", is(1)) + .extract().jsonPath().getMap("[0]"); + + assertFalse(document.containsKey("name")); + } + @Test public void updateDocumentType() { given() diff --git a/integration/jackson/src/test/java/com/blazebit/persistence/integration/jackson/EntityViewAwareObjectMapperTest.java b/integration/jackson/src/test/java/com/blazebit/persistence/integration/jackson/EntityViewAwareObjectMapperTest.java index f21a625358..40f92074a8 100644 --- a/integration/jackson/src/test/java/com/blazebit/persistence/integration/jackson/EntityViewAwareObjectMapperTest.java +++ b/integration/jackson/src/test/java/com/blazebit/persistence/integration/jackson/EntityViewAwareObjectMapperTest.java @@ -27,6 +27,7 @@ import com.blazebit.persistence.view.spi.type.EntityViewProxy; import com.fasterxml.jackson.annotation.JsonIgnore; import com.fasterxml.jackson.databind.DeserializationFeature; +import com.fasterxml.jackson.databind.JsonNode; import com.fasterxml.jackson.databind.ObjectMapper; import com.fasterxml.jackson.databind.ObjectReader; import com.fasterxml.jackson.databind.exc.IgnoredPropertyException; @@ -41,6 +42,9 @@ import java.util.List; import java.util.Set; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertFalse; + /** * @author Christian Beikov * @since 1.4.0 @@ -71,7 +75,7 @@ public void testReadView() throws Exception { EntityViewAwareObjectMapper mapper = mapper(NameView.class); ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(NameView.class)); NameView view = objectReader.readValue("{\"id\": 1}"); - Assert.assertEquals(1L, view.getId()); + assertEquals(1L, view.getId()); Assert.assertNull(view.getName()); } @@ -95,10 +99,10 @@ public Type getOwnerType() { } })); List views = objectReader.readValue("[{\"id\": 1}, {\"id\": 2}]"); - Assert.assertEquals(2, views.size()); - Assert.assertEquals(1L, views.get(0).getId()); + assertEquals(2, views.size()); + assertEquals(1L, views.get(0).getId()); Assert.assertNull(views.get(0).getName()); - Assert.assertEquals(2L, views.get(1).getId()); + assertEquals(2L, views.get(1).getId()); Assert.assertNull(views.get(0).getName()); } @@ -114,9 +118,9 @@ public void testReadViewWithSetters() throws Exception { EntityViewAwareObjectMapper mapper = mapper(ReadViewWithSetters.class, NameView.class); ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(ReadViewWithSetters.class)); ReadViewWithSetters view = objectReader.readValue("{\"id\": 1, \"name\": \"test\", \"parent\": {\"id\": 2}}"); - Assert.assertEquals(1L, view.getId()); - Assert.assertEquals("test", view.getName()); - Assert.assertEquals(2L, view.getParent().getId()); + assertEquals(1L, view.getId()); + assertEquals("test", view.getName()); + assertEquals(2L, view.getParent().getId()); } @EntityView(SomeEntity.class) @@ -134,9 +138,9 @@ public void testUpdatableView() throws Exception { EntityViewAwareObjectMapper mapper = mapper(UpdateViewWithSetters.class, NameView.class); ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(UpdateViewWithSetters.class)); UpdateViewWithSetters view = objectReader.readValue("{\"id\": 1, \"name\": \"test\", \"parent\": {\"id\": 2}}"); - Assert.assertEquals(1L, view.getId()); - Assert.assertEquals("test", view.getName()); - Assert.assertEquals(2L, view.getParent().getId()); + assertEquals(1L, view.getId()); + assertEquals("test", view.getName()); + assertEquals(2L, view.getParent().getId()); } @EntityView(SomeEntity.class) @@ -156,8 +160,8 @@ public void testCreatableView() throws Exception { ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(CreatableViewWithSetters.class)); CreatableViewWithSetters view = objectReader.readValue("{\"name\": \"test\", \"parent\": {\"id\": 2}}"); Assert.assertTrue(((EntityViewProxy) view).$$_isNew()); - Assert.assertEquals("test", view.getName()); - Assert.assertEquals(2L, view.getParent().getId()); + assertEquals("test", view.getName()); + assertEquals(2L, view.getParent().getId()); } @EntityView(SomeEntity.class) @@ -176,10 +180,10 @@ public void testCreatableAndUpdatableView() throws Exception { EntityViewAwareObjectMapper mapper = mapper(CreatableAndUpdatableViewWithSetters.class, NameView.class); ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(CreatableAndUpdatableViewWithSetters.class)); CreatableAndUpdatableViewWithSetters view = objectReader.readValue("{\"id\": 1, \"name\": \"test\", \"parent\": {\"id\": 2}}"); - Assert.assertFalse(((EntityViewProxy) view).$$_isNew()); - Assert.assertEquals(1L, view.getId()); - Assert.assertEquals("test", view.getName()); - Assert.assertEquals(2L, view.getParent().getId()); + assertFalse(((EntityViewProxy) view).$$_isNew()); + assertEquals(1L, view.getId()); + assertEquals("test", view.getName()); + assertEquals(2L, view.getParent().getId()); } @Test @@ -188,8 +192,8 @@ public void testCreatableAndUpdatableViewWithoutId() throws Exception { ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(CreatableAndUpdatableViewWithSetters.class)); CreatableAndUpdatableViewWithSetters view = objectReader.readValue("{\"name\": \"test\", \"parent\": {\"id\": 2}}"); Assert.assertTrue(((EntityViewProxy) view).$$_isNew()); - Assert.assertEquals("test", view.getName()); - Assert.assertEquals(2L, view.getParent().getId()); + assertEquals("test", view.getName()); + assertEquals(2L, view.getParent().getId()); } @EntityView(SomeEntity.class) @@ -210,9 +214,9 @@ public void testCreatableAndUpdatableViewWithoutNestedUpdatableView() throws Exc ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(CreatableAndUpdatableViewWithNested.class)); CreatableAndUpdatableViewWithNested view = objectReader.readValue("{\"name\": \"test\", \"parent\": {\"id\": 2, \"name\": \"parent\"}}"); Assert.assertTrue(((EntityViewProxy) view).$$_isNew()); - Assert.assertEquals("test", view.getName()); - Assert.assertEquals(2L, view.getParent().getId()); - Assert.assertEquals("parent", view.getParent().getName()); + assertEquals("test", view.getName()); + assertEquals(2L, view.getParent().getId()); + assertEquals("parent", view.getParent().getName()); } @Test @@ -221,9 +225,9 @@ public void testCreatableAndUpdatableViewWithoutNestedUpdatableViewWithoutId() t ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(CreatableAndUpdatableViewWithNested.class)); CreatableAndUpdatableViewWithNested view = objectReader.readValue("{\"name\": \"test\", \"parent\": {\"name\": \"parent\"}}"); Assert.assertTrue(((EntityViewProxy) view).$$_isNew()); - Assert.assertEquals("test", view.getName()); + assertEquals("test", view.getName()); Assert.assertTrue(((EntityViewProxy) view.getParent()).$$_isNew()); - Assert.assertEquals("parent", view.getParent().getName()); + assertEquals("parent", view.getParent().getName()); } @EntityView(SomeEntity.class) @@ -244,9 +248,9 @@ public void testCreatableWithCollection() throws Exception { ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(CreatableWithCollection.class)); CreatableWithCollection view = objectReader.readValue("{\"name\": \"test\", \"children\": [{\"name\": \"parent\"}]}"); Assert.assertTrue(((EntityViewProxy) view).$$_isNew()); - Assert.assertEquals("test", view.getName()); - Assert.assertEquals(mapper.getEntityViewManager().getChangeModel(view).get("children").getInitialState(), view.getChildren()); - Assert.assertEquals(1, view.getChildren().size()); + assertEquals("test", view.getName()); + assertEquals(mapper.getEntityViewManager().getChangeModel(view).get("children").getInitialState(), view.getChildren()); + assertEquals(1, view.getChildren().size()); } @EntityView(SomeEntity.class) @@ -266,9 +270,9 @@ public void testCreatableWithCollectionWithSetter() throws Exception { ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(CreatableWithCollectionWithSetter.class)); CreatableWithCollectionWithSetter view = objectReader.readValue("{\"name\": \"test\", \"children\": [{\"name\": \"parent\"}]}"); Assert.assertTrue(((EntityViewProxy) view).$$_isNew()); - Assert.assertEquals("test", view.getName()); - Assert.assertEquals(mapper.getEntityViewManager().getChangeModel(view).get("children").getInitialState(), view.getChildren()); - Assert.assertEquals(1, view.getChildren().size()); + assertEquals("test", view.getName()); + assertEquals(mapper.getEntityViewManager().getChangeModel(view).get("children").getInitialState(), view.getChildren()); + assertEquals(1, view.getChildren().size()); } @EntityView(SomeEntity.class) @@ -292,7 +296,7 @@ public void testCreatableWithIgnoreId() throws Exception { objectReader.readValue("{\"id\": 1, \"name\": \"test\"}"); Assert.fail("Expected failure"); } catch (IgnoredPropertyException ex) { - Assert.assertEquals("id", ex.getPropertyName()); + assertEquals("id", ex.getPropertyName()); } } @@ -311,11 +315,11 @@ public void testUpdatableWithCollectionWithSetter() throws Exception { EntityViewAwareObjectMapper mapper = mapper(UpdatableWithCollectionWithSetter.class, NameView.class); ObjectReader objectReader = mapper.readerFor(mapper.getObjectMapper().constructType(UpdatableWithCollectionWithSetter.class)); UpdatableWithCollectionWithSetter view = objectReader.readValue("{\"id\":1, \"name\": \"test\", \"children\": [{\"id\": 1}]}"); - Assert.assertFalse(((EntityViewProxy) view).$$_isNew()); - Assert.assertEquals(1L, view.getId()); - Assert.assertEquals("test", view.getName()); - Assert.assertEquals(1L, view.getChildren().iterator().next().getId()); - Assert.assertEquals(1, view.getChildren().size()); + assertFalse(((EntityViewProxy) view).$$_isNew()); + assertEquals(1L, view.getId()); + assertEquals("test", view.getName()); + assertEquals(1L, view.getChildren().iterator().next().getId()); + assertEquals(1, view.getChildren().size()); } @EntityView(SomeEntity.class) @@ -328,4 +332,26 @@ interface UpdatableWithCollectionWithSetter { Set getChildren(); void setChildren(Set children); } + + @EntityView(SomeEntity.class) + @CreatableEntityView + static abstract class ViewWithJsonIgnore { + @IdMapping + public abstract long getId(); + public abstract void setId(long id); + @JsonIgnore + public abstract String getName(); + public abstract void setName(String name); + } + + @Test + public void testJsonIgnore() throws Exception { + EntityViewAwareObjectMapper mapper = mapper(ViewWithJsonIgnore.class); + ViewWithJsonIgnore view = mapper.getEntityViewManager().create(ViewWithJsonIgnore.class); + view.setId(1L); + view.setName("Joe"); + JsonNode viewAsJsonTree = mapper.getObjectMapper().readTree(mapper.getObjectMapper().writeValueAsString(view)); + assertEquals(1L, viewAsJsonTree.get("id").asLong()); + assertFalse(viewAsJsonTree.has("name")); + } } diff --git a/integration/quarkus/deployment/src/main/java/com/blazebit/persistence/integration/quarkus/deployment/BlazePersistenceProcessor.java b/integration/quarkus/deployment/src/main/java/com/blazebit/persistence/integration/quarkus/deployment/BlazePersistenceProcessor.java index 15e88c1f25..4f75640ef8 100644 --- a/integration/quarkus/deployment/src/main/java/com/blazebit/persistence/integration/quarkus/deployment/BlazePersistenceProcessor.java +++ b/integration/quarkus/deployment/src/main/java/com/blazebit/persistence/integration/quarkus/deployment/BlazePersistenceProcessor.java @@ -82,7 +82,7 @@ public EntityViewConfigurationBuildItem produceEntityViewConfigurationBuildItem( EntityViewConfiguration evc = EntityViews.createDefaultConfiguration(); for (String entityViewClassName : entityViewsBuildItem.getEntityViewClassNames()) { try { - evc.addEntityView(Class.forName(entityViewClassName)); + evc.addEntityView(Thread.currentThread().getContextClassLoader().loadClass(entityViewClassName)); } catch (ClassNotFoundException e) { throw new RuntimeException(e); } @@ -169,11 +169,13 @@ void reflection(EntityViewsBuildItem entityViewsBuildItem, // add fromString methods from entity view id types for (EntityViewMapping entityViewMapping : entityViewConfigurationBuildItem.getEntityViewConfiguration().getEntityViewMappings()) { - reflectionProducer.produce(ReflectiveClassBuildItem.builder(entityViewMapping.getIdAttribute().getDeclaredType()) - .constructors(true) - .methods(true) - .build() - ); + if (entityViewMapping.getIdAttribute() != null) { + reflectionProducer.produce(ReflectiveClassBuildItem.builder(entityViewMapping.getIdAttribute().getDeclaredType()) + .constructors(true) + .methods(true) + .build() + ); + } } }