Commit 51044735 authored by Matija Obreza's avatar Matija Obreza

Crop otherNames is lazy-loaded

parent 4462b801
......@@ -25,6 +25,7 @@ import java.util.Locale;
import java.util.Map;
import javax.persistence.Cacheable;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
......@@ -65,8 +66,7 @@ public class Crop extends GlobalVersionedAuditedModel implements AclAwareModel {
private String shortName;
@Column(name = "otherName", nullable = false)
//FetchType.LAZY doesn't work in unit tests, it causes org.hibernate.LazyInitializationException
@ElementCollection(fetch = FetchType.EAGER)
@ElementCollection(fetch = FetchType.LAZY)
@CollectionTable(name = "cropname", joinColumns = @JoinColumn(name = "cropId", referencedColumnName = "id"), uniqueConstraints = { @UniqueConstraint(columnNames = "otherName") })
@OrderBy("otherName")
private List<String> otherNames;
......@@ -86,7 +86,7 @@ public class Crop extends GlobalVersionedAuditedModel implements AclAwareModel {
* Rules
*/
@JsonIgnore
@OneToMany(mappedBy = "crop", cascade = {}, orphanRemoval = true)
@OneToMany(mappedBy = "crop", cascade = { CascadeType.REMOVE }, orphanRemoval = true)
private List<CropRule> cropRules;
@Transient
......@@ -100,7 +100,7 @@ public class Crop extends GlobalVersionedAuditedModel implements AclAwareModel {
@Transient
@JsonIgnore
private transient JsonNode i18nJU;
public String getName() {
return name;
......
......@@ -74,17 +74,23 @@ public class CropServiceImpl implements CropService {
@Override
public Crop getCrop(String shortName) {
Crop crop = cropRepository.findByShortName(shortName);
// Find crop by alias when null
if (crop == null) {
// Find crop by alias
crop = cropRepository.findByOtherNames(shortName);
}
// Lazy load otherNames
if (crop != null && crop.getOtherNames() != null)
crop.getOtherNames().size();
return crop;
}
@PreAuthorize("hasRole('ADMINISTRATOR')")
@Override
@Transactional
@CacheEvict(allEntries=true, value=CACHE_CROPS)
@CacheEvict(allEntries = true, value = CACHE_CROPS)
public Crop delete(Crop crop) {
cropRepository.delete(crop);
crop.setId(null);
......@@ -104,7 +110,8 @@ public class CropServiceImpl implements CropService {
List<Crop> crops = cropRepository.findAll();
// Fetch otherNames list
crops.stream().forEach(c -> {
c.getOtherNames().size();
if (c.getOtherNames() != null)
c.getOtherNames().size();
});
return crops;
}
......@@ -115,7 +122,8 @@ public class CropServiceImpl implements CropService {
final List<Crop> crops = cropRepository.findAll();
// Fetch otherNames list
crops.stream().forEach(c -> {
c.getOtherNames().size();
if (c.getOtherNames() != null)
c.getOtherNames().size();
});
Collections.sort(crops, new Comparator<Crop>() {
@Override
......@@ -260,7 +268,7 @@ public class CropServiceImpl implements CropService {
@Override
@PreAuthorize("hasRole('ADMINISTRATOR')")
@Transactional(readOnly = false)
@CacheEvict(allEntries=true, value=CACHE_CROPS)
@CacheEvict(allEntries = true, value = CACHE_CROPS)
public Crop addCrop(String shortName, String name, String description, String i18n) {
LOG.info("Adding crop " + shortName);
final Crop crop = new Crop();
......@@ -281,7 +289,7 @@ public class CropServiceImpl implements CropService {
@Override
@PreAuthorize("hasRole('ADMINISTRATOR') or hasPermission(#crop, 'ADMINISTRATION')")
@Transactional(readOnly = false)
@CacheEvict(allEntries=true, value=CACHE_CROPS)
@CacheEvict(allEntries = true, value = CACHE_CROPS)
public Crop updateCrop(Crop crop, String name, String description, String i18n) {
LOG.info("Updating crop " + crop);
......
package org.genesys2.tests.resttests;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.hamcrest.Matchers.*;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
import static org.springframework.restdocs.request.RequestDocumentation.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.util.ArrayList;
import java.util.List;
......@@ -46,6 +34,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@Transactional(transactionManager = "transactionManager")
public class ApiDocumentation extends AbstractRestTest {
private static final Log LOG = LogFactory.getLog(ApiDocumentation.class);
......@@ -115,27 +104,27 @@ public class ApiDocumentation extends AbstractRestTest {
public void createCropTest() throws Exception {
LOG.info("Start test-method createCropTest");
cropRepository.deleteAll();
mockMvc.perform(post("/api/v0/crops")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(new Object() {
public String shortName="maize";
public String name="Maize";
public String shortName="rice";
public String name="Rice";
public String description="Crop description in EN";
public String[] otherNames = { "ris", "riž" };
})))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.id", is(notNullValue())))
.andExpect(jsonPath("$.version", is(0)))
.andExpect(jsonPath("$.shortName", is("maize")))
.andExpect(jsonPath("$.shortName", is("rice")))
.andExpect(jsonPath("$.i18n", is(nullValue())))
.andExpect(jsonPath("$.name", is("Maize")))
.andExpect(jsonPath("$.name", is("Rice")))
.andExpect(jsonPath("$.description", is("Crop description in EN")))
.andDo(document("crop-create",
requestFields(
fieldWithPath("shortName").description("Crop short name or code (e.g. maize)"),
fieldWithPath("name").description("Crop name in English"),
fieldWithPath("otherNames").type(JsonFieldType.ARRAY).optional().description("Alternative spellings of the crop name"),
fieldWithPath("description").optional().description("Crop description in English")
),
responseFields(
......@@ -145,6 +134,7 @@ public class ApiDocumentation extends AbstractRestTest {
fieldWithPath("shortName").description("Crop short name or code (e.g. maize)"),
fieldWithPath("description").description("Crop description in English"),
fieldWithPath("rdfUri").type(JsonFieldType.STRING).optional().description("URI of RDF term describing the crop"),
fieldWithPath("otherNames").type(JsonFieldType.ARRAY).optional().description("Alternative spellings of the crop name"),
fieldWithPath("i18n").type(JsonFieldType.STRING).optional().description("i18n map"),
fieldWithPath("createdBy").ignored(),
fieldWithPath("createdDate").ignored(),
......@@ -177,6 +167,7 @@ public class ApiDocumentation extends AbstractRestTest {
fieldWithPath("name").description("Crop name in English"),
fieldWithPath("shortName").description("Crop short name or code (e.g. maize)"),
fieldWithPath("description").description("Crop description in English"),
fieldWithPath("otherNames").type(JsonFieldType.ARRAY).optional().description("Alternative spellings of the crop name"),
fieldWithPath("rdfUri").type(JsonFieldType.STRING).optional().description("URI of RDF term describing the crop"),
fieldWithPath("i18n").type(JsonFieldType.STRING).optional().description("i18n map"),
fieldWithPath("createdBy").ignored(),
......@@ -191,16 +182,18 @@ public class ApiDocumentation extends AbstractRestTest {
@Test
public void deleteCropTest() throws Exception {
LOG.info("Start test-method deleteCropTest");
createCropTest();
mockMvc.perform(delete("/api/v0/crops/{shortName}", crop.getShortName())
mockMvc.perform(delete("/api/v0/crops/{shortName}", "rice")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.id", is(nullValue())))
.andExpect(jsonPath("$.version", is(0)))
.andExpect(jsonPath("$.shortName", is("maize")))
.andExpect(jsonPath("$.shortName", is("rice")))
.andExpect(jsonPath("$.i18n", is(nullValue())))
.andExpect(jsonPath("$.name", is("Maize")))
.andExpect(jsonPath("$.name", is("Rice")))
.andExpect(jsonPath("$.description", is("Crop description in EN")))
.andDo(document("crop-delete", pathParameters(
parameterWithName("shortName").description("Crop short name or code (e.g. maize)")
......
package org.genesys2.tests.resttests;
import static org.hamcrest.Matchers.hasSize;
import static org.hamcrest.Matchers.is;
import static org.hamcrest.Matchers.notNullValue;
import static org.hamcrest.Matchers.nullValue;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.document;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.documentationConfiguration;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.delete;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.get;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.post;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.put;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.restdocs.payload.PayloadDocumentation.requestFields;
import static org.springframework.restdocs.payload.PayloadDocumentation.responseFields;
import static org.springframework.restdocs.request.RequestDocumentation.parameterWithName;
import static org.springframework.restdocs.request.RequestDocumentation.pathParameters;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.content;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.jsonPath;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.status;
import static org.hamcrest.Matchers.*;
import static org.springframework.restdocs.mockmvc.MockMvcRestDocumentation.*;
import static org.springframework.restdocs.mockmvc.RestDocumentationRequestBuilders.*;
import static org.springframework.restdocs.payload.PayloadDocumentation.*;
import static org.springframework.restdocs.request.RequestDocumentation.*;
import static org.springframework.test.web.servlet.result.MockMvcResultMatchers.*;
import java.util.ArrayList;
import java.util.List;
......@@ -35,6 +23,8 @@ import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.MediaType;
import org.springframework.restdocs.RestDocumentation;
import org.springframework.restdocs.payload.JsonFieldType;
import org.springframework.test.annotation.Commit;
import org.springframework.test.annotation.Rollback;
import org.springframework.test.web.servlet.MockMvc;
import org.springframework.test.web.servlet.setup.MockMvcBuilders;
import org.springframework.transaction.annotation.Transactional;
......@@ -46,6 +36,7 @@ import com.fasterxml.jackson.databind.JsonNode;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.SerializationFeature;
@Transactional(transactionManager = "transactionManager")
public class CropsControllerTest extends AbstractRestTest {
private static final Log LOG = LogFactory.getLog(CropsControllerTest.class);
......@@ -78,7 +69,6 @@ public class CropsControllerTest extends AbstractRestTest {
.withPort(443)).build();
crop = cropService.addCrop("maize", "Maize", "Crop description in EN", null);
cropRule = cropService.addCropRule(crop, "Zea", "mays", true);
List<CropRule> cropRules = new ArrayList<>();
......@@ -88,7 +78,8 @@ public class CropsControllerTest extends AbstractRestTest {
@After
public void tearDown() {
cropRepository.deleteAll();
cropRuleRepository.delete(cropRule);
cropRepository.delete(crop);
}
@Test
......@@ -115,22 +106,20 @@ public class CropsControllerTest extends AbstractRestTest {
public void createCropTest() throws Exception {
LOG.info("Start test-method createCropTest");
cropRepository.deleteAll();
mockMvc.perform(post("/api/v0/crops")
.contentType(MediaType.APPLICATION_JSON)
.content(objectMapper.writeValueAsString(new Object() {
public String shortName="maize";
public String name="Maize";
public String shortName="rice";
public String name="Rice";
public String description="Crop description in EN";
})))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.id", is(notNullValue())))
.andExpect(jsonPath("$.version", is(0)))
.andExpect(jsonPath("$.shortName", is("maize")))
.andExpect(jsonPath("$.shortName", is("rice")))
.andExpect(jsonPath("$.i18n", is(nullValue())))
.andExpect(jsonPath("$.name", is("Maize")))
.andExpect(jsonPath("$.name", is("Rice")))
.andExpect(jsonPath("$.description", is("Crop description in EN")))
.andDo(document("crop-create",
requestFields(
......@@ -146,7 +135,7 @@ public class CropsControllerTest extends AbstractRestTest {
fieldWithPath("description").description("Crop description in English"),
fieldWithPath("rdfUri").type(JsonFieldType.STRING).optional().description("URI of RDF term describing the crop"),
fieldWithPath("i18n").type(JsonFieldType.STRING).optional().description("i18n map"),
fieldWithPath("otherNames").ignored(),
fieldWithPath("otherNames").type(JsonFieldType.ARRAY).optional().description("Alternative spellings of the crop name"),
fieldWithPath("createdBy").ignored(),
fieldWithPath("createdDate").ignored(),
fieldWithPath("lastModifiedBy").ignored(),
......@@ -180,7 +169,7 @@ public class CropsControllerTest extends AbstractRestTest {
fieldWithPath("description").description("Crop description in English"),
fieldWithPath("rdfUri").type(JsonFieldType.STRING).optional().description("URI of RDF term describing the crop"),
fieldWithPath("i18n").type(JsonFieldType.STRING).optional().description("i18n map"),
fieldWithPath("otherNames").ignored(),
fieldWithPath("otherNames").type(JsonFieldType.ARRAY).optional().description("Alternative spellings of the crop name"),
fieldWithPath("createdBy").ignored(),
fieldWithPath("createdDate").ignored(),
fieldWithPath("lastModifiedBy").ignored(),
......@@ -194,15 +183,17 @@ public class CropsControllerTest extends AbstractRestTest {
public void deleteCropTest() throws Exception {
LOG.info("Start test-method deleteCropTest");
mockMvc.perform(delete("/api/v0/crops/{shortName}", crop.getShortName())
createCropTest();
mockMvc.perform(delete("/api/v0/crops/{shortName}", "rice")
.contentType(MediaType.APPLICATION_JSON))
.andExpect(status().isOk())
.andExpect(content().contentType(MediaType.APPLICATION_JSON))
.andExpect(jsonPath("$.id", is(nullValue())))
.andExpect(jsonPath("$.version", is(0)))
.andExpect(jsonPath("$.shortName", is("maize")))
.andExpect(jsonPath("$.shortName", is("rice")))
.andExpect(jsonPath("$.i18n", is(nullValue())))
.andExpect(jsonPath("$.name", is("Maize")))
.andExpect(jsonPath("$.name", is("Rice")))
.andExpect(jsonPath("$.description", is("Crop description in EN")))
.andDo(document("crop-delete", pathParameters(
parameterWithName("shortName").description("Crop short name or code (e.g. maize)")
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment