public class ObjectMapperUtils {
private static ModelMapper modelMapper = new ModelMapper();
/**
* Model mapper property setting are specified in the following block.
* Default property matching strategy is set to Strict see {@link MatchingStrategies}
* Custom mappings are added using {@link ModelMapper#addMappings(PropertyMap)}
*/
static {
modelMapper = new ModelMapper();
modelMapper.getConfiguration().setMatchingStrategy(MatchingStrategies.STRICT);
}
/**
* Hide from public usage.
*/
private ObjectMapperUtils() {
}
/**
* Note: outClass object must have default constructor with no arguments
*
* @param type of result object.
* @param type of source object to map from.
* @param entity entity that needs to be mapped.
* @param outClass class of result object.
* @return new object of outClass type.
*/
public static <D, T> D map(final T entity, Class<D> outClass) {
return modelMapper.map(entity, outClass);
}
/**
* Note: outClass object must have default constructor with no arguments
*
* @param entityList list of entities that needs to be mapped
* @param outCLass class of result list element
* @param type of objects in result list
* @param type of entity in entityList
* @return list of mapped object with type.
*/
public static <D, T> List<D> mapAll(final Collection<T> entityList, Class<D> outCLass) {
return entityList.stream()
.map(entity -> map(entity, outCLass))
.collect(Collectors.toList());
}
/**
* Maps {@code source} to {@code destination}.
*
* @param source object to map from
* @param destination object to map to
*/
public static <S, D> D map(final S source, D destination) {
modelMapper.map(source, destination);
return destination;
}
}
Friday, January 4, 2019
Model Mapper Issues
Thursday, December 13, 2018
Code without writing Transformers
When we write Java coding we might come across scenarios where we might need to convert data types | transform one type to another
eg: Let's take a simple REST call. We call GET department. First method call will be for Controller and Controller will return a department (DTO)object. To get this from Controller, we call service layer and from Service Layer Repository (DAO) will be called. From Dao we get and Entity object. In this scenario, we have two types of objects naming DTO and DAO.
This scenario comes where we normally does not expose Entity layer objects to API level.
So we need to transform DTO to DAO and vice versa.
To do this, we need to write a methods to Transform and reverse transform.
To do this easily we can use "Model Mapper"
http://modelmapper.org/getting-started/
We can simply call "map" method and no need to write Transform methods.
Below is the example.
public class Address {
private String street;
private String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
---------------------------------------------------------------------------------------
public class Customer {
private String name;
public Customer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
Gradle dependency
compileOnly('org.projectlombok:lombok')
compile group: 'org.modelmapper', name: 'modelmapper', version: '2.3.0'
eg: Let's take a simple REST call. We call GET department. First method call will be for Controller and Controller will return a department (DTO)object. To get this from Controller, we call service layer and from Service Layer Repository (DAO) will be called. From Dao we get and Entity object. In this scenario, we have two types of objects naming DTO and DAO.
This scenario comes where we normally does not expose Entity layer objects to API level.
So we need to transform DTO to DAO and vice versa.
To do this, we need to write a methods to Transform and reverse transform.
To do this easily we can use "Model Mapper"
http://modelmapper.org/getting-started/
We can simply call "map" method and no need to write Transform methods.
Below is the example.
public class Address {
private String street;
private String city;
public Address(String street, String city) {
this.street = street;
this.city = city;
}
public String getStreet() {
return street;
}
public void setStreet(String street) {
this.street = street;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
---------------------------------------------------------------------------------------
public class Customer {
private String name;
public Customer(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
----------------------------------------------------------------------------------------
public class Order {
private Customer customer;
private Address billingAddress;
private Address shippingAddress;
public Order(Customer customer, Address billingAddress, Address shippingAddress) {
this.customer = customer;
this.billingAddress = billingAddress;
this.shippingAddress = shippingAddress;
}
public Customer getCustomer() {
return customer;
}
public void setCustomer(Customer customer) {
this.customer = customer;
}
public Address getShippingAddress() {
return shippingAddress;
}
public void setShippingAddress(Address shippingAddress) {
this.shippingAddress = shippingAddress;
}
public Address getBillingAddress() {
return billingAddress;
}
public void setBillingAddress(Address billingAddress) {
this.billingAddress = billingAddress;
}
}
---------------------------------------------------------------------------------------------
import org.modelmapper.ModelMapper;
public class FlatteningExample1 {
public static void main(String[] args) {
// TODO Auto-generated method stub
Customer customer = new Customer("Joe Smith");
Address billingAddress = new Address("2233 Pike Street", "Seattle");
Address shippingAddress = new Address("1234 Market Street", "San Francisco");
Order order = new Order(customer, billingAddress, shippingAddress);
System.out.println(customer);
ModelMapper modelMapper = new ModelMapper();
OrderDTO dto = modelMapper.map(order, OrderDTO.class);
System.out.println(dto);
System.out.println(dto.getCustomerName() + "= " + order.getCustomer().getName());
}
}
You can further remove getter, Setters and other boiler plate code using "lombok"
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LAddress {
private String street;
private String city;
}
--------------------------------------------------------------------------------------------------------------
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LCustomer {
private String name;
}
--------------------------------------------------------------------------------------------------------------
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class LOrder {
private LCustomer customer;
private LAddress billingAddress;
private LAddress shippingAddress;
}
--------------------------------------------------------------------------------------------------------------
import org.modelmapper.ModelMapper;
public class LFlatteningExample1 {
public static void main(String[] args) {
String name = "Joe Smith";
String street = "2233 Pike Street";
String city = "Seattle";
String shipStreet = "1234 Market Street";
String shipCity = "San Francisco";
LCustomer customer = LCustomer.builder().name(name).build();
LAddress billingAddress = LAddress.builder().street(street).city(city).build();
LAddress shippingAddress = LAddress.builder().street(shipStreet).city(shipCity).build();
LOrder order = LOrder.builder().customer(customer).billingAddress(billingAddress)
.shippingAddress(shippingAddress).build();
System.out.println(customer);
ModelMapper mapper = new ModelMapper();
LOrderDTO orderDTO = mapper.map(order, LOrderDTO.class);
System.out.println(orderDTO);
}
}
--------------------------------------------------------------------------------------------------------------
Gradle dependency
compileOnly('org.projectlombok:lombok')
compile group: 'org.modelmapper', name: 'modelmapper', version: '2.3.0'
Tuesday, December 11, 2018
Error in npm install
I get below when i tried to run "npm install" for a module i checke out from git.
----------------------------------------------------------------------------------------------------------------
npm ERR! code E404
npm ERR! 404 Not Found: har-validator@5.1.2
npm ERR! A complete log of this run can be found in:
------------------------------------------------------------------------------------------------------------------
Issue :
with " har-validator" in "package-lock.json" file
Solution
Delete the "package-lock.json" and re run "npm install"
----------------------------------------------------------------------------------------------------------------
npm ERR! code E404
npm ERR! 404 Not Found: har-validator@5.1.2
npm ERR! A complete log of this run can be found in:
------------------------------------------------------------------------------------------------------------------
Issue :
with " har-validator" in "package-lock.json" file
Solution
Delete the "package-lock.json" and re run "npm install"
Thursday, November 29, 2018
FindBug Malicious code vulnerability Warnings Solutions
FindBug Malicious code vulnerability Warnings
EI_EXPOSE_REP: May expose internal representation by returning reference to mutable object
EI_EXPOSE_REP2: May expose internal representation by incorporating reference to mutable object
EI_EXPOSE_REP: May expose internal representation by returning reference to mutable object
EI_EXPOSE_REP2: May expose internal representation by incorporating reference to mutable object
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate != null ? (Date) createdDate.clone() : null;
}
public Date getCreatedDate() {
return createdDate != null ? (Date) createdDate.clone() : null;
}
Wednesday, November 14, 2018
dependencies.dependency.version' for org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:jar is missing. @ line 49, column 15
Application : I am building Spring boot application and when i add the dependancy for Eureka, Zuul etc gave me the error
dependencies.dependency.version' for org.springframework.cloud:spring-cloud-starter-netflix-eureka-client:jar is missing. @ line 49, column 15
Reason:
This is beacuse , cannot find in normal repo. we have to tell how to find this.. since belongs to netflix stack.
i added below "dependencyManagement" and "repositories"
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
you may add the version also if this does not work under "properties"
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.M1</spring-cloud.version>
</properties>
Hibernate changing column names of the table
I have created a simple table with two fields and called simple CRUD operation to view the data.
Technolgy: Springboot, hibernate(JPA), MySQL
table name = cluster
CREATE DATABASE IF NOT EXISTS `myDb`;
USE `myDb`;
DROP TABLE cluster;
CREATE TABLE IF NOT EXISTS `cluster` (
`clusterId` bigint(5) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
PRIMARY KEY (`clusterId`)
) ENGINE=InnoDB;
INSERT INTO `cluster` (`clusterId`, `name`) VALUES
(1, 'C1'),
(2, 'C2'),
(3, 'C3');
but when i call rest http://localhost:8888/entity/clusters
this creating another field in the table with name "cluster_id"
Reason:
hibernate , Springboot provides the default naming strategy as the "ImprovedNamingStrategy"
https://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/cfg/ImprovedNamingStrategy.html
This creating names according to the built in strategy
eg: clusterId --> cluster_id
Cluster --> cluster
Solution:
change naming strategy
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
For Information below is the complete code
--------------
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;
@RestController
@RequestMapping("entity")
public class ClusterController {
@Autowired
private ClusterServiceImpl clusterService;
@GetMapping("clusters")
public ResponseEntity
List clusList = clusterService.getClusterList();
return new ResponseEntity
}
@GetMapping("cluster/{id}")
public ResponseEntity getClusterById(@PathVariable("id") Integer id) {
Cluster cluster = clusterService.getClusterById(id);
return new ResponseEntity(cluster, HttpStatus.OK);
}
@PostMapping("cluster")
public ResponseEntity createCluster(@RequestBody Cluster cluster, UriComponentsBuilder builder) {
boolean flag = clusterService.addCluster(cluster);
if (!flag) {
return new ResponseEntity(HttpStatus.CONFLICT);
}
HttpHeaders headers = new HttpHeaders();
headers.setLocation(builder.path("/cluster/{id}").buildAndExpand(cluster.getId()).toUri());
return new ResponseEntity(headers, HttpStatus.CREATED);
}
@PutMapping("cluster")
public ResponseEntity updateCluster(@RequestBody Cluster cluster) {
clusterService.updateCluster(cluster);
return new ResponseEntity(cluster, HttpStatus.OK);
}
@DeleteMapping("cluster/{id}")
public ResponseEntity deleteCluster(@PathVariable("id") Integer id) {
clusterService.deleteCluster(id);
return new ResponseEntity(HttpStatus.NO_CONTENT);
}
}
----------------
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "cluster")
public class Cluster {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "clusterId")
private long id;
@Column(name = "name")
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
------------------------
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ClusterServiceImpl implements ClusterService {
@Autowired
private ClusterRepository clusterRepository;
@Override
public List getClusterList() {
List clusterList = new ArrayList<>();
clusterRepository.findAll().forEach(elment -> clusterList.add(elment));
return clusterList;
}
@Override
public Cluster getClusterById(long id) {
Cluster cluster = clusterRepository.findById(id).get();
return cluster;
}
@Override
public boolean addCluster(Cluster cluster) {
Cluster clus = clusterRepository.save(cluster);
return false;
}
@Override
public void updateCluster(Cluster cluster) {
clusterRepository.save(cluster);
}
@Override
public void deleteCluster(long clusterId) {
// Cluster cluster = new Cluster();
// cluster.setId(clusterId);
clusterRepository.delete(getClusterById(clusterId));
}
}
---------
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public interface ClusterService {
List getClusterList();
Cluster getClusterById(long id);
boolean addCluster(Cluster cluster);
void updateCluster(Cluster cluster);
void deleteCluster(long clusterId);
}
Technolgy: Springboot, hibernate(JPA), MySQL
table name = cluster
CREATE DATABASE IF NOT EXISTS `myDb`;
USE `myDb`;
DROP TABLE cluster;
CREATE TABLE IF NOT EXISTS `cluster` (
`clusterId` bigint(5) NOT NULL AUTO_INCREMENT,
`name` varchar(200) NOT NULL,
PRIMARY KEY (`clusterId`)
) ENGINE=InnoDB;
INSERT INTO `cluster` (`clusterId`, `name`) VALUES
(1, 'C1'),
(2, 'C2'),
(3, 'C3');
but when i call rest http://localhost:8888/entity/clusters
this creating another field in the table with name "cluster_id"
Reason:
hibernate , Springboot provides the default naming strategy as the "ImprovedNamingStrategy"
https://docs.jboss.org/hibernate/orm/4.3/javadocs/org/hibernate/cfg/ImprovedNamingStrategy.html
This creating names according to the built in strategy
eg: clusterId --> cluster_id
Cluster --> cluster
Solution:
change naming strategy
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
For Information below is the complete code
--------------
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.DeleteMapping;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.util.UriComponentsBuilder;
@RestController
@RequestMapping("entity")
public class ClusterController {
@Autowired
private ClusterServiceImpl clusterService;
@GetMapping("clusters")
public ResponseEntity
- > getClusterList() {
List
return new ResponseEntity
- >(clusList, HttpStatus.OK);
}
@GetMapping("cluster/{id}")
public ResponseEntity
Cluster cluster = clusterService.getClusterById(id);
return new ResponseEntity
}
@PostMapping("cluster")
public ResponseEntity
boolean flag = clusterService.addCluster(cluster);
if (!flag) {
return new ResponseEntity
}
HttpHeaders headers = new HttpHeaders();
headers.setLocation(builder.path("/cluster/{id}").buildAndExpand(cluster.getId()).toUri());
return new ResponseEntity
}
@PutMapping("cluster")
public ResponseEntity
clusterService.updateCluster(cluster);
return new ResponseEntity
}
@DeleteMapping("cluster/{id}")
public ResponseEntity
clusterService.deleteCluster(id);
return new ResponseEntity
}
}
----------------
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.Table;
@Entity
@Table(name = "cluster")
public class Cluster {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "clusterId")
private long id;
@Column(name = "name")
private String name;
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
------------------------
import java.util.ArrayList;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
@Service
public class ClusterServiceImpl implements ClusterService {
@Autowired
private ClusterRepository clusterRepository;
@Override
public List
List
clusterRepository.findAll().forEach(elment -> clusterList.add(elment));
return clusterList;
}
@Override
public Cluster getClusterById(long id) {
Cluster cluster = clusterRepository.findById(id).get();
return cluster;
}
@Override
public boolean addCluster(Cluster cluster) {
Cluster clus = clusterRepository.save(cluster);
return false;
}
@Override
public void updateCluster(Cluster cluster) {
clusterRepository.save(cluster);
}
@Override
public void deleteCluster(long clusterId) {
// Cluster cluster = new Cluster();
// cluster.setId(clusterId);
clusterRepository.delete(getClusterById(clusterId));
}
}
---------
import java.util.List;
import org.springframework.stereotype.Service;
@Service
public interface ClusterService {
List
Cluster getClusterById(long id);
boolean addCluster(Cluster cluster);
void updateCluster(Cluster cluster);
void deleteCluster(long clusterId);
}
--------------------
import org.springframework.data.repository.CrudRepository;
public interface ClusterRepository extends CrudRepository {
}
-----------------
application.properties
spring.jpa.hibernate.ddl-auto=update
#spring.jpa.hibernate.naming.implicit-strategy=org.hibernate.cfg.DefaultComponentSafeNamingStrategy
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.datasource.url=jdbc:mysql://localhost:3306/myDB
spring.datasource.username=root
spring.datasource.password=123
spring.datasource.hikari.connection-timeout=20000
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.maximum-pool-size=12
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.max-lifetime=1200000
spring.jpa.properties.hibernate.dialect = org.hibernate.dialect.MySQLDialect
spring.jpa.properties.hibernate.id.new_generator_mappings = false
spring.jpa.properties.hibernate.format_sql = true
logging.level.org.hibernate.SQL=DEBUG
logging.level.org.hibernate.type.descriptor.sql.BasicBinder=TRACE
server.port=8888
eureka.client.serviceUrl.defaultZone= http://localhost:1111/eureka/
eureka.instance.leaseRenewalIntervalInSeconds=5
Tuesday, October 2, 2018
aw-mode is unavailable courtesy of Hyper-V. (VERR_SUPDRV_NO_RAW_MODE_HYPER_V_ROOT).
You must have experienced below error when trying to start your VM. eg: start Linux server from Oracle VM Virtual Box.
I have Orcle VM and docker installed in the machine
OS = Windows 10
Below is the error:
Failed to open a session for the virtual machine LinOra_1.
Raw-mode is unavailable courtesy of Hyper-V. (VERR_SUPDRV_NO_RAW_MODE_HYPER_V_ROOT).
Result Code: E_FAIL (0x80004005)
Component: ConsoleWrap
Interface: IConsole {872da645-4a9b-1727-bee2-5585105b9eed}
Power up failed (vrc=VERR_SUPDRV_NO_RAW_MODE_HYPER_V_ROOT
Solution:
Disable the hyper v from windows OS.
When running docker, this is enabled. So it's difficult to run docker and Oracle VM at same time.
I have Orcle VM and docker installed in the machine
OS = Windows 10
Below is the error:
Failed to open a session for the virtual machine LinOra_1.
Raw-mode is unavailable courtesy of Hyper-V. (VERR_SUPDRV_NO_RAW_MODE_HYPER_V_ROOT).
Result Code: E_FAIL (0x80004005)
Component: ConsoleWrap
Interface: IConsole {872da645-4a9b-1727-bee2-5585105b9eed}
Power up failed (vrc=VERR_SUPDRV_NO_RAW_MODE_HYPER_V_ROOT
Solution:
Disable the hyper v from windows OS.
When running docker, this is enabled. So it's difficult to run docker and Oracle VM at same time.
Subscribe to:
Posts (Atom)