NullPointerException when want to access lazy loaded collection in jUnit test - spring-mvc

In my Spring app i have Two entity:
#Entity
public class Category {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
....
#OneToOne
#Cascade({CascadeType.ALL})
#JoinColumn(name="page_id")
private Page page;
#OneToMany(fetch=FetchType.LAZY, mappedBy="category")
private List<Shop> shop;
..getters and setters
}
And
#Entity
public class Shop {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
....
#OneToOne(mappedBy="shop")
private Settings settings;
#ManyToOne
#Cascade({CascadeType.SAVE_UPDATE})
#JoinColumn(name = "category_id")
private Category category;
#OneToOne
#Cascade({CascadeType.ALL})
#JoinColumn(name = "page_id")
private Page page;
...getters and setters
}
And in my test jUnit i added some category and some shop with this category, when i want to access to list of shops current category i have a error
java.lang.NullPointerException ....
My test:
#ContextConfiguration(locations = {
"classpath:security-context.xml",
"classpath:dao-context.xml"
})
#RunWith(SpringJUnit4ClassRunner.class)
#WebAppConfiguration
#TransactionConfiguration(transactionManager="transactionManager", defaultRollback=false)
#Transactional
public class CategoryTest {
Shop shop1 = new Shop(....);
Shop shop1 = new Shop(....);
Category category1 = new Category(....);
Category category2 = new Category(....);
#Test
public void someTest(){
shop1.setCategory(category1);
shop2.setCategory(category2);
shopService.add(shop1);
shopService.add(shop2);
assertEquals(2, shopService.getAllShop().size());
assertEquals(2, categoryService.getAllShop().size());
//IN THIS LINE I HAVE A ERROR
assertEquals(1, categoryService.getCategory(category1.getId()).getShop().size());
}
}
For access to lazy atribute i added to my web.xml filtr: org.springframework.orm.hibernate3.support.OpenSessionInViewFilter This working properly in front app not in jUnit test.
Which point I make an error?

The lazy loading only takes place whist inside a transaction, when the session is open. So you get null in the test method unless you initialize the lazy loaded collection beforehand.
Another similar question

Related

how do i create roles and use those roles in JSPS?

how do I create user defined roles and then how do I use them to code my JSPS to present them according to the user role type in a spring MVC web application
If I understand you correctly.
Use jstl.
<%# taglib prefix = "c" uri = "http://java.sun.com/jsp/jstl/core" %>
With the " if " condition, you can create different menu calls for different users.
JSTL - Core Tag
<c:if test="${example != null}">
<center>
${example}
</center>
</c:if>
Below are the steps to do that.
1.Create a role entity.
2.Create a user entity.
3.Establish relationship between both tables like (OneToMany or #ManyToMany based on your requirement)
4.Insert a role in table.
5.create a user by assigning the role to the user.
6.Once DB relationships are done then inside JSP page you can get role and put a condition to check that and you are done.
Code for step 1 :
#Entity
public class Role implements GrantedAuthority {
private static final long serialVersionUID = 1L;
#NotNull
private String roleName;
private String description;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
//getters and setters and other fields like roleName,description etc.
}
Step 2 &3:
#Entity
public class User extends BaseEntity implements UserDetails, Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private Long id;
#Column(unique = true)
private String userId;
#ManyToOne
private Role role;
//getters and setters and other fields like password,etc.
}
Step 6 :
<sec:authorize ifAnyGranted="ROLE_ADMIN" >
write code here which only ADMIN can see
</sec:authorize>

On Save, the foreign key value in child table is empty for REST XML service

This is a REST XML service. On Save, the foreign key value in child table is empty.
The #Id's are using sequence and it works fine. Im not added the sequence generator code here.
//Main Entity
------------
#Entity
#Table(name="REQUEST")
public class MsaDisabScreenRequest implements Serializable {
#Id
#Column(name="REQUEST_ID")
private long requestId; //sequence
#OneToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE }, fetch = FetchType.LAZY, mappedBy="msaDisabScreenRequest")
private Set<ReqDetail> disabilities;
}
Child Entity
#Entity
#Table(name="REQ_DETAILS")
public class ReqDetail implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name="MAP_ID")
private long mapId; //sequence
#Column(name="TYPE_ID")
private long disabilityTypeId;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="REQUEST_ID")
privateRequest msaDisabScreenRequest;
}
This is the dto that I'm using to map.
//Main Dto
#XmlRootElement(name="DisabilityRequest")
#XmlAccessorType(XmlAccessType.FIELD)
public class MsaDisabScreenRequestDto implements Serializable {
private static final long serialVersionUID = 1L;
private long requestId;
#NotNull
private Set<DetailDto> disabilities;
}
//Child Dto
#XmlRootElement(name="disabilities")
#XmlAccessorType(XmlAccessType.FIELD)
public class MsaDisabScreenReqDetailDto implements Serializable {
private static final long serialVersionUID = 1L;
private long mapId;
private long disabilityTypeId;
#XmlTransient
private RequestDto msaDisabScreenRequest;
}
This is the controller
#RequestMapping(value = ApiPath.REQUEST, method = RequestMethod.POST, produces = { "application/xml"})
public #ResponseBody ResultDecorator saveScreeningRequest(#Valid #RequestBody RequestDto requestDto) throws Exception {
.
.
.
.
}
save code which is using jpa repository to persist.
Implementation code only added the code releavant to save
#Autowired
private OrikaBeanMapper mapper;
.
.
.
.
.
.
.
// mapping
Request request = mapper.map(requestDto,Request.class);
Request Res = msaRepository.save(request);
This is the request payload I'm sending
<?xml version="1.0" encoding="UTF-8" ?>
<DisabilityRequest>
<disabilities>
<disabilityTypeId>9</disabilityTypeId>
</disabilities>
</DisabilityRequest>
Here the requestId is added as empty REQ_DETAILS table. All other entries passed are persisted.
Let me know if you need any further details.
When fetch type is LAZY, the data set are empty. You can use Fetch type EAGER but its expensive

Mongo Java Connectivity - Only Insert once

I have a Mongo - Java MVC Spring 4 connectivity. My insert operations work only once, they don't do a second insert in the collection. What could be the problem?
Here's my code.
import org.springframework.data.mongodb.core.mapping.Document;
#Document(collection="subject")
public class Employee {
#Id
#GeneratedValue(strategy=GenerationType.SEQUENCE)
private int id;
private String name;
private String email;
private String address;
private String telephone;
strong text
...
public class EmployeeDAOImpl implements EmployeeDAO {
MongoTemplate mongoTemplate;
public MongoTemplate getMongoTemplate() {
return mongoTemplate;
}
public void setMongoTemplate(MongoTemplate mongoTemplate) {
this.mongoTemplate = mongoTemplate;
}
#Override
public void addEmployee(Employee employee) {
mongoTemplate.save(employee);;
}
#Override
public List<Employee> getAllEmployees() {
// TODO Auto-generated method stub
return mongoTemplate.findAll(Employee.class);
}
#GeneratedValue(strategy=GenerationType.SEQUENCE) annotation is for JPA and not for Mongo.
Make sure that you import the #Id from the mongo package and ID should be auto generated by Mongo.
The first insert works because int has default value of 0 and the second time it tries to insert with the same key.
if you want to have custom ids generated, here is a great tutorial for that: https://www.baeldung.com/spring-boot-mongodb-auto-generated-field

Nested entity in request body is ignored

The domain model is
An industry has many companies
A company belongs to an industry
So I have my entity classes:
#Entity
public class Industry {
#Id #GeneratedValue
private Long id;
private String name;
#OneToMany(targetEntity = Company.class, fetch = FetchType.LAZY, mappedBy = "industry")
private Collection<Company> companies = new ArrayList<>(0);
// Getters and setters
}
and
#Entity
public class Company {
#Id #GeneratedValue
private Long id;
private String name;
#ManyToOne(cascade = CascadeType.DETACH, fetch = FetchType.EAGER, optional = false)
private Industry industry;
// Getters and setters
}
My controller:
#RestController
#RequestMapping("/companies")
public class CompaniesController extends ControllerBase {
#RequestMapping(method = RequestMethod.POST)
public Company create(#RequestBody Company company) {
company.getIndustry(); // returns null
// ...
}
}
When I send request POST /companies with request body
{
"name": "Walmart",
"industry": {
"id": 1
}
}
I found that company.getIndustry() always returns null. How can I make the controller accept nested entities?
Entities are session based. They usually work on basis of Lazy loading I.e only the first level is loaded and other attributes are loaded on Demand. You cannot pass it from one layer to other. (service to controller)
The correct way to do it. Have a Value object (a simple class) n the controller. Use it between front end and back end. Send the same value object to service. And use the entity only between Service and DAo layer
public class CompanyVO{
private Long id;
private String name;
private IndustryVO industryVO; // create similar class
// Getters and setters
}
#RestController
#RequestMapping("/companies")
public class CompaniesController extends ControllerBase {
#RequestMapping(method = RequestMethod.POST)
public Company create(#RequestBody CompanyVO companyVO) {
companyVO.getIndustry(); // returns null
// ...
}
}
This may be because you need another Spring message converter instead of the default one. Just add jackson to your pom.xml and Spring will use MappingJackson2HttpMessageConverter.
<dependency>
<groupId>com.fasterxml.jackson.core</groupId>
<artifactId>jackson-databind</artifactId>
<version>2.8.5</version>
</dependency>

Adobe Flex Builder WSDL classes autogenerator generates weird files

Adobe Flex Builder WSDL classes autogenerator generates wierd files.
For example:
http://ws.cdyne.com/WeatherWS/Weather.asmx?wsdl
After importing it generates these files:
ArrayOfForecast.as
ArrayOfWeatherDescription.as
ArrayOfWeatherDescription0.as
BaseWeather.as
BaseWeatherSchema.as
Forecast.as
ForecastReturn.as
ForecastReturn0.as
GetCityForecastByZIPResultEvent.as
GetCityForecastByZIP_request.as
GetCityWeatherByZIPResultEvent.as
GetCityWeatherByZIP_request.as
GetWeatherInformationResultEvent.as
GetWeatherInformation_request.as
IWeather.as
POP.as
Temp.as
Weather.as
WeatherDescription.as
WeatherReturn.as
WeatherReturn0.as
What are these ZERO at the end files for?
That was an example for service with 3 operations. My real wsdl has much more methods and types.
UPDATED
At the same time Java generates much cleaner set of classes:
Forecast.java
ForecastReturn.java
POP.java
Temp.java
WeatherDescription.java
Weather.java
WeatherLocator.java
WeatherReturn.java
WeatherSoap12Stub.java
WeatherSoap.java
WeatherSoapProxy.java
WeatherSoapStub.java
It's not noticeable for such small service, but for bigger service with more operations and types it generates hundreds of classes. I have doubt that Adobe Flex team does wsdl classes autogeneration in proper way.
UPDATE-2
WeatherReturn.as:
public class WeatherReturn
{
/**
* Constructor, initializes the type class
*/
public function WeatherReturn() {}
public var Success:Boolean;
public var ResponseText:String;
public var State:String;
public var City:String;
public var WeatherStationCity:String;
public var WeatherID:Number;
public var Description:String;
public var Temperature:String;
public var RelativeHumidity:String;
public var Wind:String;
public var Pressure:String;
public var Visibility:String;
public var WindChill:String;
public var Remarks:String;
}
WeatherReturn0.as:
public class WeatherReturn0
{
/**
* Constructor, initializes the type class
*/
public function WeatherReturn0() {}
public var WeatherReturn:com.cdyne.WeatherReturn;
}
WeatherReturn.java:
public class WeatherReturn implements java.io.Serializable {
private boolean success;
private java.lang.String responseText;
private java.lang.String state;
private java.lang.String city;
private java.lang.String weatherStationCity;
private short weatherID;
private java.lang.String description;
private java.lang.String temperature;
private java.lang.String relativeHumidity;
private java.lang.String wind;
private java.lang.String pressure;
private java.lang.String visibility;
private java.lang.String windChill;
private java.lang.String remarks;
// Skipped constructors and getter/setter
private java.lang.Object __equalsCalc = null;
public synchronized boolean equals(java.lang.Object obj)
private boolean __hashCodeCalc = false;
public synchronized int hashCode()
// Type metadata
private static org.apache.axis.description.TypeDesc typeDesc = new org.apache.axis.description.TypeDesc(WeatherReturn.class, true);
static {
typeDesc.setXmlType(new javax.xml.namespace.QName("http://ws.cdyne.com/WeatherWS/", "WeatherReturn"));
org.apache.axis.description.ElementDesc elemField = new org.apache.axis.description.ElementDesc();
elemField.setFieldName("success");
elemField.setXmlName(new javax.xml.namespace.QName("http://ws.cdyne.com/WeatherWS/", "Success"));
elemField.setXmlType(new javax.xml.namespace.QName("http://www.w3.org/2001/XMLSchema", "boolean"));
elemField.setNillable(false);
typeDesc.addFieldDesc(elemField);
elemField = new org.apache.axis.description.ElementDesc();
elemField.setFieldName("responseText");
// More typedesc here ...
}
public static org.apache.axis.description.TypeDesc getTypeDesc() {
public static org.apache.axis.encoding.Serializer getSerializer(
public static org.apache.axis.encoding.Deserializer getDeserializer(
}
I left only methods signatures for Java example and skipped getters/setters.

Resources