The following code is my soap web service with CRUD operations:
UserService.java
package com.gpcoder.ws;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.jws.soap.SOAPBinding;
#WebService
#SOAPBinding(style = SOAPBinding.Style.RPC)
public interface UserService {
#WebMethod
int insert(User user);
#WebMethod
boolean update(User user);
#WebMethod
boolean delete(int id);
#WebMethod
User get(int id);
#WebMethod
User[] getAll();
}
UserServiceImpl.java
package com.gpcoder.ws;
import java.util.HashMap;
import java.util.Map;
import javax.jws.WebService;
#WebService(endpointInterface = "com.gpcoder.ws.UserService")
public class UserServiceImpl implements UserService {
private static final Map<Integer, User> USERS = new HashMap<>();
#Override
public int insert(User user) {
Integer id = generateUniqueId();
user.setId(id);
USERS.put(id, user);
return id;
}
private int generateUniqueId() {
return USERS.keySet().stream().max((x1, x2) -> x1 - x2).orElse(0) + 1;
}
#Override
public boolean update(User user) {
return USERS.put(user.getId(), user) != null;
}
#Override
public boolean delete(int id) {
return USERS.remove(id) != null;
}
#Override
public User get(int id) {
return USERS.getOrDefault(id, new User());
}
#Override
public User[] getAll() {
return USERS.values().toArray(new User[0]);
}
}
SoapPublisher.java
package com.gpcoder.ws;
import javax.xml.ws.Endpoint;
public class SoapPublisher {
public static final String WS_URL = "http://localhost:8080/ws/users";
public static void main(String[] args) {
Endpoint.publish(WS_URL, new UserServiceImpl());
System.out.println("Server is published!");
}
}
I would like to use the feign-soap library to call these soap API. I tried to implement it following the feign-soap document. Here is my client-side code:
pom.xml
<!-- https://mvnrepository.com/artifact/io.github.openfeign/feign-soap -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-soap</artifactId>
<version>10.2.3</version>
</dependency>
UserService.java
import java.util.ArrayList;
import java.util.List;
import com.gpcoder.model.User;
import feign.Headers;
import feign.RequestLine;
#Headers({ "Content-Type: text/xml" })
public interface UserService {
#RequestLine("POST /get")
#Headers({ "SOAPAction: get" })
String getUser(int id);
#RequestLine("POST /insert")
#Headers({ "SOAPAction: insert" })
String createUser(User user);
#RequestLine("POST /update")
#Headers({ "SOAPAction: update" })
String updateUser(User user);
#RequestLine("POST /delete")
#Headers({ "SOAPAction: delete" })
String deleteUser(int id);
default List<String> getUsers(int... ids) {
List<String> orders = new ArrayList<>();
for (int id : ids) {
orders.add(this.getUser(id));
}
return orders;
}
}
FeignClientCreator.java
import feign.Feign;
import feign.jaxb.JAXBContextFactory;
import feign.soap.SOAPDecoder;
import feign.soap.SOAPEncoder;
import feign.soap.SOAPErrorDecoder;
public class FeignClientCreator {
public static final String BASE_URL = "http://localhost:8080/ws/users";
public static <T> T getService(Class<T> clazz) {
JAXBContextFactory jaxbFactory = new JAXBContextFactory.Builder()
.withMarshallerJAXBEncoding("UTF-8")
.withMarshallerSchemaLocation("http://apihost http://apihost/schema.xsd")
.build();
return Feign.builder()
.encoder(new SOAPEncoder(jaxbFactory))
.decoder(new SOAPDecoder(jaxbFactory))
.errorDecoder(new SOAPErrorDecoder())
.target(clazz, BASE_URL);
}
}
FeignClientExample.java
import java.io.IOException;
import com.gpcoder.helper.FeignClientCreator;
import com.gpcoder.model.User;
import com.gpcoder.service.UserService;
public class FeignClientExample {
private static UserService userService;
public static void main(String[] args) throws IOException {
userService = FeignClientCreator.getService(UserService.class);
createUser();
}
private static void createUser() throws IOException {
User user1 = new User();
user1.setId(1);
user1.setUsername("gpcoder.com");
System.out.println("createUser1: " + userService.createUser(user1));
}
}
I don't know where is my code wrong. When I run my program, it show error log:
Exception in thread "main" javax.xml.ws.soap.SOAPFaultException: Cannot find dispatch method for {}user
at feign.soap.SOAPErrorDecoder.decode(SOAPErrorDecoder.java:68)
at feign.SynchronousMethodHandler.executeAndDecode(SynchronousMethodHandler.java:149)
at feign.SynchronousMethodHandler.invoke(SynchronousMethodHandler.java:78)
at feign.ReflectiveFeign$FeignInvocationHandler.invoke(ReflectiveFeign.java:103)
at com.sun.proxy.$Proxy3.createUser(Unknown Source)
at com.gpcoder.FeignClientExample.createUser(FeignClientExample.java:32)
at com.gpcoder.FeignClientExample.main(FeignClientExample.java:16)
Does anyone already worked with this library or have some documents about it please give me some information?
Related
Good morning, I am new to Spring Boot, and I am performing a rest service that must invoke a procedure stored in the database, the question is that you receive the mobile and must return a code and result, as shown below:
This is my code:
Main Class
package com.app.validacion;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
#SpringBootApplication
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
Controller
package com.app.validacion.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.app.validacion.dao.DriverBonificadosRepository;
import com.app.validacion.entity.RespuestaVo;
#RestController
public class DriverBonificadosController {
#Autowired
private DriverBonificadosRepository dao;
#GetMapping("/service/{movil}")
public RespuestaVo ConsultarMovil(#PathVariable String movil) {
return dao.validarClienteBonifiado(movil);
}
}
Repository
package com.app.validacion.dao;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.repository.CrudRepository;
import com.app.validacion.entity.DriverBonificados;
import com.app.validacion.entity.RespuestaVo;
public interface DriverBonificadosRepository extends CrudRepository<DriverBonificados, Integer> {
#Procedure(procedureName="ValidacionClienteBonificado")
RespuestaVo validarClienteBonifiado(String pMovil);
}
My entity
import javax.persistence.NamedStoredProcedureQueries;
import javax.persistence.NamedStoredProcedureQuery;
import javax.persistence.ParameterMode;
import javax.persistence.StoredProcedureParameter;
import javax.persistence.Table;
#NamedStoredProcedureQueries({
#NamedStoredProcedureQuery(
name="SPValidationClienteBonus4G",
procedureName="ValidacionClienteBonificado",
parameters = {
#StoredProcedureParameter(mode=ParameterMode.IN, name="p_movil",type=String.class),
#StoredProcedureParameter(mode=ParameterMode.OUT, name="code",type=String.class),
#StoredProcedureParameter(mode=ParameterMode.OUT, name="result",type=String.class),
})
})
#Entity
#Table
public class DriverBonificados {
#Id
private int id;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getMovil() {
return movil;
}
public void setMovil(String movil) {
this.movil = movil;
}
public String getContador() {
return contador;
}
public void setContador(String contador) {
this.contador = contador;
}
public Date getFecha_driver() {
return fecha_driver;
}
public void setFecha_driver(Date fecha_driver) {
this.fecha_driver = fecha_driver;
}
public Date getFecha_alta() {
return fecha_alta;
}
public void setFecha_alta(Date fecha_alta) {
this.fecha_alta = fecha_alta;
}
public Date getFecha_fin() {
return fecha_fin;
}
public void setFecha_fin(Date fecha_fin) {
this.fecha_fin = fecha_fin;
}
public Date getCodigo_transaccion() {
return codigo_transaccion;
}
public void setCodigo_transaccion(Date codigo_transaccion) {
this.codigo_transaccion = codigo_transaccion;
}
private String movil;
private String contador;
private Date fecha_driver;
private Date fecha_alta;
private Date fecha_fin;
private Date codigo_transaccion;
My Class RespuestaVo
package com.app.validacion.entity;
public class RespuestaVo {
private String code;
private String result;
public String getCode() {
return code;
}
public void setCode(String code) {
this.code = code;
}
public String getResult() {
return result;
}
public void setResult(String result) {
this.result = result;
}
}
And I get the following error (the mobile parameter must be received as a String, since in the database it is found as Varchar):
Anyone have an idea how this problem could be solved? I need to consult via Stored Procedue if or if
UPDATE
Using #Query and modifying the code as follows:
package com.app.validacion.dao;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.jpa.repository.query.Procedure;
import org.springframework.data.repository.CrudRepository;
import org.springframework.data.repository.query.Param;
import com.app.validacion.entity.DriverBonificados;
import com.app.validacion.entity.RespuestaVo;
public interface DriverBonificadosRepository extends CrudRepository<DriverBonificados, Integer> {
#Query(nativeQuery = true,value = "call ValidacionClienteBonificado(:movil)")
RespuestaVo validarClienteBonifiado(#Param("movil") String pMovil);
}
I get the following error:
org.springframework.core.convert.ConverterNotFoundException: No
converter found capable of converting from type
[org.springframework.data.jpa.repository.query.AbstractJpaQuery$TupleConverter$TupleBackedMap]
to type [com.app.validacion.entity.RespuestaVo] at
org.springframework.core.convert.support.GenericConversionService.handleConverterNotFound(GenericConversionService.java:321)
~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE] at
org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:194)
~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE] at
org.springframework.core.convert.support.GenericConversionService.convert(GenericConversionService.java:174)
~[spring-core-5.2.1.RELEASE.jar:5.2.1.RELEASE] at
org.springframework.data.repository.query.ResultProcessor$ProjectingConverter.convert(ResultProcessor.java:297)
~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE] at
org.springframework.data.repository.query.ResultProcessor$ChainingConverter.lambda$and$0(ResultProcessor.java:217)
~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE] at
org.springframework.data.repository.query.ResultProcessor$ChainingConverter.convert(ResultProcessor.java:228)
~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE] at
org.springframework.data.repository.query.ResultProcessor.processResult(ResultProcessor.java:170)
~[spring-data-commons-2.2.1.RELEASE.jar:2.2.1.RELEASE] at
org.springframework.data.jpa.repository.query.AbstractJpaQuery.doExecute(AbstractJpaQuery.java:157)
~[spring-data-jpa-2.2.1.RELEASE.jar:2.2.1.RELEASE]
SOLVED
I managed to solve my problem, using the #Query annotation, and building an interface for the response I was going to receive, in these cases with 2 methods (according to the number of parameters that I will receive), and With this I got my answer in a Json, I leave the interface code below:
public interface RespuestaVo {
String getCode();
String getResult();
}
I recommend using #Query to run Stored Procedue with Spring Boot
Try this -
#GetMapping("/service/{movil}")
public RespuestaVo ConsultarMovil(#PathVariable("movil") String movil) {
return dao.validarClienteBonifiado(movil);
}
I have seen the name binding strategy from jersey to shield the api, it's pretty cool for authentication, and it's pretty cool to just annotate the endpoints you want to authenticate, and in jersey you can bind the annotation to the filter.
does anybody knows how to achieve this in spring boot ?
Check maven dependencies
Check the maven file should have spring-boot-starter-jersey dependency in it.
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-jersey</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Create REST APIs
Now create some JAX-RS resources which we will access into testing phase. I have created UserResource class.
UserResource.java
package com.howtodoinjava.jerseydemo;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Map;
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;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Response;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.NONE)
#XmlRootElement(name = "users")
#Path("/users")
public class UserResource
{
private static Map<Integer, User> DB = new HashMap<>();
#GET
#Produces("application/json")
public Users getAllUsers() {
Users users = new Users();
users.setUsers(new ArrayList<>(DB.values()));
return users;
}
#POST
#Consumes("application/json")
public Response createUser(User user) throws URISyntaxException
{
if(user.getFirstName() == null || user.getLastName() == null) {
return Response.status(400).entity("Please provide all mandatory inputs").build();
}
user.setId(DB.values().size()+1);
user.setUri("/user-management/"+user.getId());
DB.put(user.getId(), user);
return Response.status(201).contentLocation(new URI(user.getUri())).build();
}
#GET
#Path("/{id}")
#Produces("application/json")
public Response getUserById(#PathParam("id") int id) throws URISyntaxException
{
User user = DB.get(id);
if(user == null) {
return Response.status(404).build();
}
return Response
.status(200)
.entity(user)
.contentLocation(new URI("/user-management/"+id)).build();
}
#PUT
#Path("/{id}")
#Consumes("application/json")
#Produces("application/json")
public Response updateUser(#PathParam("id") int id, User user) throws URISyntaxException
{
User temp = DB.get(id);
if(user == null) {
return Response.status(404).build();
}
temp.setFirstName(user.getFirstName());
temp.setLastName(user.getLastName());
DB.put(temp.getId(), temp);
return Response.status(200).entity(temp).build();
}
#DELETE
#Path("/{id}")
public Response deleteUser(#PathParam("id") int id) throws URISyntaxException {
User user = DB.get(id);
if(user != null) {
DB.remove(user.getId());
return Response.status(200).build();
}
return Response.status(404).build();
}
static
{
User user1 = new User();
user1.setId(1);
user1.setFirstName("John");
user1.setLastName("Wick");
user1.setUri("/user-management/1");
User user2 = new User();
user2.setId(2);
user2.setFirstName("Harry");
user2.setLastName("Potter");
user2.setUri("/user-management/2");
DB.put(user1.getId(), user1);
DB.put(user2.getId(), user2);
}
}
Users.java
package com.howtodoinjava.jerseydemo;
import java.io.Serializable;
import javax.xml.bind.annotation.XmlAccessType;
import javax.xml.bind.annotation.XmlAccessorType;
import javax.xml.bind.annotation.XmlAttribute;
import javax.xml.bind.annotation.XmlElement;
import javax.xml.bind.annotation.XmlRootElement;
#XmlAccessorType(XmlAccessType.NONE)
#XmlRootElement(name = "user")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#XmlAttribute(name = "id")
private int id;
#XmlAttribute(name="uri")
private String uri;
#XmlElement(name = "firstName")
private String firstName;
#XmlElement(name = "lastName")
private String lastName;
// Getters and Setters
}
Configure Jersey
Now we have a JAX-RS resource and we want to access it from spring boot application which include Jersey dependency. Let’s register this resource as Jersey resource.
package com.howtodoinjava.jerseydemo;
import org.glassfish.jersey.server.ResourceConfig;
import org.springframework.stereotype.Component;
#Component
public class JerseyConfig extends ResourceConfig
{
public JerseyConfig()
{
register(SecurityFilter.class);
register(UserResource.class);
}
}
Look at the #Component annotation. It enables this class to be
registered while spring boot auto scans the java classes in source
folder.
ResourceConfig provides advanced capabilities to simplify
registration of JAX-RS components.
SecurityFilter class is the actual auth details processor which we
will see later in this tutorial.
Extend spring boot application with SpringBootServletInitializer.
package com.howtodoinjava.jerseydemo;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.boot.web.support.SpringBootServletInitializer;
#SpringBootApplication
public class JerseydemoApplication extends SpringBootServletInitializer
{
public static void main(String[] args)
{
new JerseydemoApplication().configure(new SpringApplicationBuilder(JerseydemoApplication.class)).run(args);
}
}
Secure REST APIs with JAX-RS Annotations
Now when our APIs are ready, we will start securing them. Let’s annotate the APIs with JAX-RS annotations based on their desired access level and user roles allowed to access them.
package com.howtodoinjava.jerseydemo;
#XmlAccessorType(XmlAccessType.NONE)
#XmlRootElement(name = "users")
#Path("/users")
public class UserResource
{
private static Map<Integer, User> DB = new HashMap<>();
#GET
#PermitAll
#Produces("application/json")
public Users getAllUsers() {
Users users = new Users();
users.setUsers(new ArrayList<>(DB.values()));
return users;
}
#POST
#Consumes("application/json")
#RolesAllowed("ADMIN")
public Response createUser(User user) throws URISyntaxException
{
if(user.getFirstName() == null || user.getLastName() == null) {
return Response.status(400).entity("Please provide all mandatory inputs").build();
}
user.setId(DB.values().size()+1);
user.setUri("/user-management/"+user.getId());
DB.put(user.getId(), user);
return Response.status(201).contentLocation(new URI(user.getUri())).build();
}
#GET
#Path("/{id}")
#Produces("application/json")
#PermitAll
public Response getUserById(#PathParam("id") int id) throws URISyntaxException
{
User user = DB.get(id);
if(user == null) {
return Response.status(404).build();
}
return Response
.status(200)
.entity(user)
.contentLocation(new URI("/user-management/"+id)).build();
}
#PUT
#Path("/{id}")
#Consumes("application/json")
#Produces("application/json")
#RolesAllowed("ADMIN")
public Response updateUser(#PathParam("id") int id, User user) throws URISyntaxException
{
User temp = DB.get(id);
if(user == null) {
return Response.status(404).build();
}
temp.setFirstName(user.getFirstName());
temp.setLastName(user.getLastName());
DB.put(temp.getId(), temp);
return Response.status(200).entity(temp).build();
}
#DELETE
#Path("/{id}")
#RolesAllowed("ADMIN")
public Response deleteUser(#PathParam("id") int id) throws URISyntaxException {
User user = DB.get(id);
if(user != null) {
DB.remove(user.getId());
return Response.status(200).build();
}
return Response.status(404).build();
}
static
{
User user1 = new User();
user1.setId(1);
user1.setFirstName("John");
user1.setLastName("Wick");
user1.setUri("/user-management/1");
User user2 = new User();
user2.setId(2);
user2.setFirstName("Harry");
user2.setLastName("Potter");
user2.setUri("/user-management/2");
DB.put(user1.getId(), user1);
DB.put(user2.getId(), user2);
}
}
You can see the security related JAX-RS annotations in above
highlighted lines.
Write security filter using JAX-RS ContainerRequestFilter
Now it’s time to write our security filter which will examine the incoming requests, fetch the authorization information (basic auth in this example), and then will match user name and password, and finally it will verify the user’s access level by it’s role. If everything matches, API will be accessed else user will get access denied response.
package com.howtodoinjava.jerseydemo;
import java.lang.reflect.Method;
import java.util.Arrays;
import java.util.Base64;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.StringTokenizer;
import javax.annotation.security.DenyAll;
import javax.annotation.security.PermitAll;
import javax.annotation.security.RolesAllowed;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ResourceInfo;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.ext.Provider;
/**
* This filter verify the access permissions for a user based on
* user name and password provided in request
* */
#Provider
public class SecurityFilter implements javax.ws.rs.container.ContainerRequestFilter
{
private static final String AUTHORIZATION_PROPERTY = "Authorization";
private static final String AUTHENTICATION_SCHEME = "Basic";
private static final Response ACCESS_DENIED = Response.status(Response.Status.UNAUTHORIZED).build();
private static final Response ACCESS_FORBIDDEN = Response.status(Response.Status.FORBIDDEN).build();
private static final Response SERVER_ERROR = Response.status(Response.Status.INTERNAL_SERVER_ERROR).build();
#Context
private ResourceInfo resourceInfo;
#Override
public void filter(ContainerRequestContext requestContext)
{
Method method = resourceInfo.getResourceMethod();
//Access allowed for all
if( ! method.isAnnotationPresent(PermitAll.class))
{
//Access denied for all
if(method.isAnnotationPresent(DenyAll.class))
{
requestContext.abortWith(ACCESS_FORBIDDEN);
return;
}
//Get request headers
final MultivaluedMap<String, String> headers = requestContext.getHeaders();
//Fetch authorization header
final List<String> authorization = headers.get(AUTHORIZATION_PROPERTY);
//If no authorization information present; block access
if(authorization == null || authorization.isEmpty())
{
requestContext.abortWith(ACCESS_DENIED);
return;
}
//Get encoded username and password
final String encodedUserPassword = authorization.get(0).replaceFirst(AUTHENTICATION_SCHEME + " ", "");
//Decode username and password
String usernameAndPassword = null;
try {
usernameAndPassword = new String(Base64.getDecoder().decode(encodedUserPassword));
} catch (Exception e) {
requestContext.abortWith(SERVER_ERROR);
return;
}
//Split username and password tokens
final StringTokenizer tokenizer = new StringTokenizer(usernameAndPassword, ":");
final String username = tokenizer.nextToken();
final String password = tokenizer.nextToken();
//Verifying Username and password
if(!(username.equalsIgnoreCase("admin") && password.equalsIgnoreCase("password"))){
requestContext.abortWith(ACCESS_DENIED);
return;
}
//Verify user access
if(method.isAnnotationPresent(RolesAllowed.class))
{
RolesAllowed rolesAnnotation = method.getAnnotation(RolesAllowed.class);
Set<String> rolesSet = new HashSet<String>(Arrays.asList(rolesAnnotation.value()));
//Is user valid?
if( ! isUserAllowed(username, password, rolesSet))
{
requestContext.abortWith(ACCESS_DENIED);
return;
}
}
}
}
private boolean isUserAllowed(final String username, final String password, final Set<String> rolesSet)
{
boolean isAllowed = false;
//Step 1. Fetch password from database and match with password in argument
//If both match then get the defined role for user from database and continue; else return isAllowed [false]
//Access the database and do this part yourself
//String userRole = userMgr.getUserRole(username);
String userRole = "ADMIN";
//Step 2. Verify user role
if(rolesSet.contains(userRole))
{
isAllowed = true;
}
return isAllowed;
}
}
I tried to create an abstract Dao. I use Spring + Hibernate.
Here's my code.
Main class with configuration:
package ru.makaek.growbox.api;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.EnableAutoConfiguration;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.autoconfigure.orm.jpa.HibernateJpaAutoConfiguration;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate5.HibernateTransactionManager;
import org.springframework.orm.hibernate5.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
import javax.sql.DataSource;
#ComponentScan(value = "ru.makaek.growbox")
#EnableAutoConfiguration(exclude = HibernateJpaAutoConfiguration.class)
#EnableTransactionManagement
#SpringBootApplication
public class Application {
#Autowired
private Environment env;
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
#Bean
public DataSource getDataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(env.getRequiredProperty("datasource.driver"));
dataSource.setUrl(env.getRequiredProperty("datasource.url"));
dataSource.setUsername(env.getRequiredProperty("datasource.username"));
dataSource.setPassword(env.getRequiredProperty("datasource.password"));
return dataSource;
}
#Bean
public LocalSessionFactoryBean getSessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(getDataSource());
sessionFactory.setPackagesToScan(new String[]{"ru.makaek.growbox"});
return sessionFactory;
}
#Bean
public HibernateTransactionManager getTransactionManager(SessionFactory sessionFactory) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(sessionFactory);
return txManager;
}
}
Rest controller
package ru.makaek.growbox.api.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.*;
import ru.makaek.growbox.api.model.data.entities.Device;
import ru.makaek.growbox.api.service.IStructureService;
#RestController
public class DeviceController extends AbstractController {
#Autowired
IStructureService structureService;
#RequestMapping(value = "/devices", method = RequestMethod.POST)
public Answer addDevice(#RequestBody Device device) {
structureService.addDevice(device);
return ok("Device has been added");
}
#RequestMapping(value = "/devices", method = RequestMethod.GET)
public Answer getDevices() {
return ok(structureService.getDevices());
}
#RequestMapping(value = "/devices/{deviceId}", method = RequestMethod.GET)
public Answer getDevice(#PathVariable Long deviceId) {
return ok(structureService.getDevice(deviceId));
}
}
Service layer. Interface
package ru.makaek.growbox.api.service;
import ru.makaek.growbox.api.model.data.entities.Device;
import java.util.List;
public interface IStructureService {
void addDevice(Device device);
List<Device> getDevices();
Device getDevice(Long deviceId);
}
Service layer. Implementation
package ru.makaek.growbox.api.service;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import ru.makaek.growbox.api.model.data.dao.base.IDao;
import ru.makaek.growbox.api.model.data.entities.Device;
import java.util.List;
#Service
#Transactional
public class StructureService implements IStructureService {
IDao<Device> deviceDao;
#Autowired
public void setDao(IDao<Device> dao) {
deviceDao = dao;
dao.setClazz(Device.class);
}
#Override
public void addDevice(Device device) {
deviceDao.create(device);
}
#Override
public List<Device> getDevices() {
return deviceDao.findAll();
}
#Override
public Device getDevice(Long deviceId) {
return deviceDao.findOne(deviceId);
}
}
Entity
package ru.makaek.growbox.api.model.data.entities;
import lombok.Data;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
#Entity(name = "devices")
#Data public class Device extends BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
DAO. Interface
package ru.makaek.growbox.api.model.data.dao.base;
import ru.makaek.growbox.api.model.data.entities.BaseEntity;
import java.util.List;
public interface IDao<T extends BaseEntity> {
T findOne(final long id);
void setClazz(Class<T> clazz);
List<T> findAll();
void create(final T entity);
T update(final T entity);
void delete(final T entity);
void deleteById(final long entityId);
}
Abstract DAO
package ru.makaek.growbox.api.model.data.dao.base;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import ru.makaek.growbox.api.model.data.entities.BaseEntity;
import ru.makaek.growbox.api.util.GBException;
import java.util.List;
public abstract class AbstractDao<T extends BaseEntity> implements IDao<T> {
private Class<T> clazz;
#Autowired
private SessionFactory sessionFactory;
public final void setClazz(Class<T> clazz) {
this.clazz = clazz;
}
public T findOne(long id) {
try {
return (T) getCurrentSession().get(clazz, id);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public List<T> findAll() {
try {
return getCurrentSession().createQuery("from " + clazz.getName()).list();
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public void create(T entity) {
try {
getCurrentSession().persist(entity);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public T update(T entity) {
try {
return (T) getCurrentSession().merge(entity);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public void delete(T entity) {
try {
getCurrentSession().delete(entity);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
public void deleteById(long entityId) {
try {
T entity = findOne(entityId);
delete(entity);
} catch (Exception e) {
throw new GBException.InternalError(e.getMessage());
}
}
protected final Session getCurrentSession() {
return sessionFactory.getCurrentSession();
}
}
DAO. Implementation
package ru.makaek.growbox.api.model.data.dao;
import org.springframework.stereotype.Repository;
import ru.makaek.growbox.api.model.data.dao.base.AbstractDao;
import ru.makaek.growbox.api.model.data.entities.Device;
#Repository
public class DeviceDao extends AbstractDao<Device> {
}
I have one trouble. When I call GET http://host:port/devices API method I have null in the clazz variable in the AbstractDao.findAll() method. When I was debugging the code i found one interesting thing: in the service layer method deviceDao.getClazz() returned needed clazz (not null). But in method AbstractDao.findAll() I have null in clazz variable. Why? Please help.
Sorry for my English and formulation. I'm new in this site, Spring and English
You are overcomplicating things. Because you are using Spring Boot it is possible to just create generic interface that extends CrudRepository and add the methods you need and are not already present in there.
Take a look here https://docs.spring.io/spring-data/data-commons/docs/1.6.1.RELEASE/reference/html/repositories.html
Since I am new to Spring and i have an issue with user service. I have admin panel and customer blog. When the Customer is logged into browser, the admin has been changed the status to Active from InActive in Table of Customer. But the user session is active. So that he can able to do process after the status is changed.
I need one common method that should be in common place. This method should be access the table and validate the user per every request. I have one controller and that should invoke the common method. Because I cannot edit code to every class. In JSP & Servlet I have handled this using doFilter. How to achieve this in Spring..
AppInitializer.java
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setMultipartConfig(getMultipartConfigElement());
}
private MultipartConfigElement getMultipartConfigElement() {
MultipartConfigElement multipartConfigElement = new MultipartConfigElement( LOCATION, MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
return multipartConfigElement;
}
private static final String LOCATION = "C:/temp/"; // Temporary location where files will be stored
private static final long MAX_FILE_SIZE = 5242880; // 5MB : Max file size.
// Beyond that size spring will throw exception.
private static final long MAX_REQUEST_SIZE = 20971520; // 20MB : Total request size containing Multi part.
private static final int FILE_SIZE_THRESHOLD = 0;
}
AppConfig.java
import javax.servlet.MultipartConfigElement;
import javax.servlet.ServletRegistration;
import org.springframework.web.servlet.support.AbstractAnnotationConfigDispatcherServletInitializer;
public class AppInitializer extends AbstractAnnotationConfigDispatcherServletInitializer {
#Override
protected Class<?>[] getRootConfigClasses() {
return new Class[] { AppConfig.class };
}
#Override
protected Class<?>[] getServletConfigClasses() {
return null;
}
#Override
protected String[] getServletMappings() {
return new String[] { "/" };
}
#Override
protected void customizeRegistration(ServletRegistration.Dynamic registration) {
registration.setMultipartConfig(getMultipartConfigElement());
}
private MultipartConfigElement getMultipartConfigElement() {
MultipartConfigElement multipartConfigElement = new MultipartConfigElement( LOCATION, MAX_FILE_SIZE, MAX_REQUEST_SIZE, FILE_SIZE_THRESHOLD);
return multipartConfigElement;
}
private static final String LOCATION = "C:/temp/"; // Temporary location where files will be stored
private static final long MAX_FILE_SIZE = 5242880; // 5MB : Max file size.
// Beyond that size spring will throw exception.
private static final long MAX_REQUEST_SIZE = 20971520; // 20MB : Total request size containing Multi part.
private static final int FILE_SIZE_THRESHOLD = 0;
}
HibernateConfiguration.java
import java.util.Properties;
import javax.sql.DataSource;
import org.hibernate.SessionFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.PropertySource;
import org.springframework.core.env.Environment;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.hibernate4.HibernateTransactionManager;
import org.springframework.orm.hibernate4.LocalSessionFactoryBean;
import org.springframework.transaction.annotation.EnableTransactionManagement;
#Configuration
#EnableTransactionManagement
#ComponentScan({ "com.ppts.configuration" })
#PropertySource(value = { "classpath:application.properties" })
public class HibernateConfiguration {
#Autowired
private Environment environment;
#Bean
public LocalSessionFactoryBean sessionFactory() {
LocalSessionFactoryBean sessionFactory = new LocalSessionFactoryBean();
sessionFactory.setDataSource(dataSource());
sessionFactory.setPackagesToScan(new String[] { "com.ppts.model" });
sessionFactory.setHibernateProperties(hibernateProperties());
return sessionFactory;
}
#Bean
public DataSource dataSource() {
DriverManagerDataSource dataSource = new DriverManagerDataSource();
dataSource.setDriverClassName(environment.getRequiredProperty("jdbc.driverClassName"));
dataSource.setUrl(environment.getRequiredProperty("jdbc.url"));
dataSource.setUsername(environment.getRequiredProperty("jdbc.username"));
dataSource.setPassword(environment.getRequiredProperty("jdbc.password"));
return dataSource;
}
private Properties hibernateProperties() {
Properties properties = new Properties();
properties.put("hibernate.dialect", environment.getRequiredProperty("hibernate.dialect"));
properties.put("hibernate.show_sql", environment.getRequiredProperty("hibernate.show_sql"));
properties.put("hibernate.format_sql", environment.getRequiredProperty("hibernate.format_sql"));
return properties;
}
#Bean
#Autowired
public HibernateTransactionManager transactionManager(SessionFactory s) {
HibernateTransactionManager txManager = new HibernateTransactionManager();
txManager.setSessionFactory(s);
return txManager;
}
}
AppController.java
package com.sample.controller;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.validation.Valid;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.MessageSource;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.security.authentication.AuthenticationTrustResolver;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.rememberme.PersistentTokenBasedRememberMeServices;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.util.FileCopyUtils;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.SessionAttributes;
import org.springframework.web.multipart.MultipartFile;
import com.sample.handler.FileHandler;
import com.sample.model.Address;
import com.sample.model.Employee;
import com.sample.model.EmployeeDocument;
import com.sample.model.EmployeeSalary;
import com.sample.model.FileBucket;
import com.sample.model.User;
import com.sample.model.UserProfile;
import com.sample.service.EmployeeDocumentService;
import com.sample.service.EmployeeSalaryService;
import com.sample.service.EmployeeService;
import com.sample.service.UserProfileService;
import com.sample.service.UserService;
import com.sample.validators.FileValidator;
#Controller
#RequestMapping("/")
#SessionAttributes("roles")
public class AppController {
#Autowired
UserService userService;
#Autowired
EmployeeService employeeService;
#Autowired
EmployeeSalaryService employeeSalaryService;
#Autowired
UserProfileService userProfileService;
#Autowired
EmployeeDocumentService employeeDocumentService;
#Autowired
FileValidator fileValidator;
#InitBinder("fileBucket")
protected void initBinderFileBucket(WebDataBinder binder) {
binder.setValidator(fileValidator);
}
#Autowired
MessageSource messageSource;
#Autowired
PersistentTokenBasedRememberMeServices persistentTokenBasedRememberMeServices;
#Autowired
AuthenticationTrustResolver authenticationTrustResolver;
#RequestMapping(value = { "/", "/list" }, method = RequestMethod.GET)
public String adminPage(ModelMap model) {
model.addAttribute("home",true);
model.addAttribute("loggedinuser", getPrincipal());
return "home";
}
#RequestMapping(value = { "/userList" }, method = RequestMethod.GET)
public String listUsers(ModelMap model) {
List<User> users = userService.findAllUsers();
model.addAttribute("users", users);
model.addAttribute("loggedinuser", getPrincipal());
return "userslist";
}
#RequestMapping(value = { "/newuser" }, method = RequestMethod.GET)
public String newUser(ModelMap model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("edit", false);
model.addAttribute("loggedinuser", getPrincipal());
return "registration";
}
#RequestMapping(value = { "/newuser" }, method = RequestMethod.POST)
public String saveUser(#Valid User user, BindingResult result,
ModelMap model) {
if (result.hasErrors()) {
return "registration";
}
if(!userService.isUserSSOUnique(user.getId(), user.getSsoId())){
FieldError ssoError =new FieldError("user","ssoId",messageSource.getMessage("non.unique.ssoId", new String[]{user.getSsoId()}, Locale.getDefault()));
result.addError(ssoError);
return "registration";
}
userService.saveUser(user);
model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " registered successfully");
model.addAttribute("loggedinuser", getPrincipal());
return "registrationsuccess";
}
#RequestMapping(value = { "/edit-user-{ssoId}" }, method = RequestMethod.GET)
public String editUser(#PathVariable String ssoId, ModelMap model) {
User user = userService.findBySSO(ssoId);
model.addAttribute("user", user);
model.addAttribute("edit", true);
model.addAttribute("loggedinuser", getPrincipal());
return "registration";
}
#RequestMapping(value = { "/edit-user-{ssoId}" }, method = RequestMethod.POST)
public String updateUser(#Valid User user, BindingResult result,
ModelMap model, #PathVariable String ssoId) {
if (result.hasErrors()) {
return "registration";
}
userService.updateUser(user);
model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " updated successfully");
model.addAttribute("loggedinuser", getPrincipal());
return "registrationsuccess";
}
//Update User and Employee By Id
#RequestMapping(value = { "/getUserById" }, method = RequestMethod.GET)
public String getUserSSOId(ModelMap model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("edit", true);
model.addAttribute("loggedinuser", getPrincipal());
return "userview";
}
#RequestMapping(value = { "/updateByUserId" }, method = RequestMethod.GET)
public String getByUserId( #ModelAttribute User userDetails,ModelMap model,BindingResult result) {
User user =userService.findBySSO(userDetails.getSsoId());
if(user!=null){
model.addAttribute("user", user);
model.addAttribute("edit", true);
model.addAttribute("loggedinuser", getPrincipal());
return "registration";
}else{
FieldError referenceIdError =new FieldError("user","ssoId",messageSource.getMessage("non.empty.userid.notexist", new String[]{userDetails.getSsoId()}, Locale.getDefault()));
result.addError(referenceIdError);
model.addAttribute("loggedinuser", getPrincipal());
return "userview";
}
}
#RequestMapping(value = { "/updateByUserId" }, method = RequestMethod.POST)
public String updateUserById(#Valid User user, BindingResult result,
ModelMap model) {
if (result.hasErrors()) {
return "registration";
}
userService.updateUser(user);
model.addAttribute("success", "User " + user.getFirstName() + " "+ user.getLastName() + " updated successfully");
model.addAttribute("loggedinuser", getPrincipal());
return "registrationsuccess";
}
#RequestMapping(value = { "/deleteByUserId" }, method = RequestMethod.GET)
public String deleteUserById(ModelMap model) {
User user = new User();
model.addAttribute("user", user);
model.addAttribute("delete", true);
model.addAttribute("loggedinuser", getPrincipal());
return "userview";
}
#RequestMapping(value = { "/deleteUserById" }, method = RequestMethod.GET)
public String deleteByuserId( #ModelAttribute User userDetails,ModelMap model,BindingResult result) {
User user=userService.findBySSO(userDetails.getSsoId());
if(user!=null){
userService.deleteUserBySSO(userDetails.getSsoId());
model.addAttribute("loggedinuser", getPrincipal());
model.addAttribute("employeeSuccess", "Employee " + user.getFirstName() + " deleted successfully");
return "registrationsuccess";
}else{
FieldError referenceIdError =new FieldError("employee","employeeReferenceId",messageSource.getMessage("non.empty.userid.notexist", new String[]{userDetails.getSsoId()}, Locale.getDefault()));
model.addAttribute("loggedinuser", getPrincipal());
result.addError(referenceIdError);
return "userview";
}
}
}
You can make create a class implementing Spring's HandlerInterceptor interface. Its preHandle method will be called for every request before request is processed by the Controller method.
Since you just want to process validation check for each request before it is handled, you can create a class extending the HandlerInterceptorAdapter class which provides convenient defaults for all methods in the HandlerInterceptor interface.
You only need to provide implementation as per your business rule for the following method
preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
Sample code below
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.web.servlet.handler.HandlerInterceptorAdapter;
public class TransactionInterceptor extends HandlerInterceptorAdapter {
#Override
public boolean preHandle(HttpServletRequest request, HttpServletResponse response, Object handler)
throws Exception {
// Your business logic goes here
// return true or false depending on whether you want the controller to handle the request or terminate request processing.
}
}
You would need to register the interceptor in Spring Config as below
#EnableWebMvc
#Configuration
public class AppConfig extends WebMvcConfigurerAdapter {
.....
#Override
public void addInterceptors(InterceptorRegistry registry) {
registry.addInterceptor(new YourNewInterceptor());
}
.....
}
You can do that also in Filter. You just have to annotate it with #Component and voila. It becomes a Spring bean. Like this:
#Component
public class UserFilter implements Filter{
#Override
public void init(FilterConfig filterConfig) throws ServletException {
}
#Override
public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
User user = (User)request.getAttribute("user");
// Do whatever you want with your user
}
#Override
public void destroy() {
}
}
I have an InboundMessageDao class which extends the BaseDao class, which implements the BaseDaoInterface class.
The BaseDao class is abstract, providing concrete and abstract member methods.
For some reason, Eclipse is claming that I did not implement persist, update, and delete from the BaseDaoInterface, even though a concrete implementation of them are provided in BaseDao.
The stranger thing is that I have another subclass, UserDao which does the same thing, but there is no error about unimplemented methods.
BaseDao.java
package com.MYPKG.data.dao;
import java.text.MessageFormat;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.springframework.core.GenericTypeResolver;
import com.MYPKG.model.User;
public abstract class BaseDao <T> implements BaseDaoInterface<T, String> {
private Session currentSession;
private Transaction currentTransaction;
public BaseDao() {
}
public Session openCurrentSession() {
currentSession = HibernateUtil.getSession();
return currentSession;
}
public Session openCurrentSessionwithTransaction() {
currentSession = HibernateUtil.getSession();
currentTransaction = currentSession.beginTransaction();
return currentSession;
}
public void closeCurrentSession() {
currentSession.close();
}
public void closeCurrentSessionwithTransaction() {
currentTransaction.commit();
currentSession.close();
}
public Session getCurrentSession() {
return currentSession;
}
public void setCurrentSession(Session currentSession) {
this.currentSession = currentSession;
}
public Transaction getCurrentTransaction() {
return currentTransaction;
}
public void setCurrentTransaction(Transaction currentTransaction) {
this.currentTransaction = currentTransaction;
}
public void persist(User entity) {
getCurrentSession().save(entity);
}
public void update(User entity) {
getCurrentSession().update(entity);
}
public abstract T findById(String id) ;
public void delete(User entity) {
getCurrentSession().delete(entity);
}
public abstract List<T> findAll() ;
public void deleteAll() {
List<T> objects = findAll();
for (T object : objects)
getCurrentSession().delete(object);
}
}
BaseDaoInterface.java
package com.MYPKG.data.dao;
import java.io.Serializable;
import java.util.List;
public interface BaseDaoInterface <T, Id extends Serializable>{
public void persist(T entity);
public void update(T entity);
public T findById(Id id);
public void delete(T entity);
public List<T> findAll();
public void deleteAll();
}
InboundMessageDao.java
package com.MYPKG.data.dao;
import java.text.MessageFormat;
import java.util.List;
import com.MYPKG.model.InboundMessage;
import com.MYPKG.model.User;
public class InboundMessageDao extends BaseDao<InboundMessage>{
///// PROBLEM
///// The type InboundMessageDao must implement the inherited abstract method BaseDaoInterface<InboundMessage,String>.update(InboundMessage)
/////
public InboundMessageDao() {
}
#Override
public InboundMessage findById(String id) {
InboundMessage object = (InboundMessage) getCurrentSession().get(InboundMessage.class, id);
return object;
}
#Override
public List<InboundMessage> findAll() {
#SuppressWarnings("unchecked")
List<InboundMessage> objects = (List<InboundMessage>) getCurrentSession().createQuery(MessageFormat.format("from {0}", "inbound_message")).list();
return objects;
}
}
UserDao.java
package com.MYPKG.data.dao;
import java.text.MessageFormat;
import java.util.List;
import org.hibernate.Session;
import org.hibernate.Transaction;
import com.MYPKG.model.User;
public class UserDao extends BaseDao<User>{;
public UserDao() {
}
public List<User> findAll() {
#SuppressWarnings("unchecked")
List<User> objects = (List<User>)getCurrentSession().createQuery(MessageFormat.format("from {0}", "user")).list();
return objects;
}
public User findById(String id) {
User object = (User) getCurrentSession().get(User.class, id);
return object;
}
}
Since your BaseDao class is defined with the generic <T>, you should define your overridden methods using T instead of User. If you add the #Override annotation to these methods, you will see that they in fact do not override the interface's methods, but instead are their own methods.