Hibernate Validator with Hibernate Dynamic Models (No Entity Class) - spring-boot

I'm using hibernate dynamic models to create a CRUD. I'm wondering how can I validate the http request (#Valid) annotation because I don't have the any entity or DTO.
#PostMapping("/signup")
public ResponseEntity<RestResponse> signup(#Valid #RequestBody Map<String, Object> user) {
var restResponse = new RestResponse<>();
restResponse.setStatusCode(HttpStatus.OK.value());
restResponse.setResponse(user);
return ResponseEntity.status(HttpStatus.OK)
.body(restResponse);
}

You can't because there is no java class that for bean validation annotations to put on and that is the sole basis for bean validation. Maybe you should switch to a proper class based model which will also make it easier to understand and debug your application

Related

Spring JPA AuditorAware is empty for nested call in service

I'am using #EntityListeners(AuditingEntityListener.class) in Spring Boot JPA application and having some issue with inserting entity. I created #RestController for REST API, #Service for extra business logic and spring's JpaRepository interfaces to access DB.
So the issue is when I want to update some entity and create some another entity in #Service (BL layer). When creating new entity from service I get exception that attribute annotated with #CreatedBy could not be null. I see that AuditorAware is empty. But if comment out creating of new entity and make update of first entity only then AuditorAware is not null and works fine.
It's also working if I create this problematic entity form #Controller.
Does anyone have similar problem and know how to solve this.
I suppose the proxyMode of AuditorAware #Bean is wrong but I don't know how to fixed it.
I changed the implementation of AuditorAware from:
#Bean
public AuditorAware<String> auditorProvider() {
return () -> {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
return Optional.ofNullable(Objects.isNull(authentication) ? null : authentication.getName());
};
}
to:
#Bean
public AuditorAware<String> auditorProvider() {
return () -> {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if (Objects.isNull(authentication) || !authentication.isAuthenticated() || !(authentication.getPrincipal() instanceof Principal)) {
return Optional.of("anonymous");
}
return Optional.of(authentication.getName());
};
}
which also populate created_by in test phase where there is no security context.

Orika mapper spring boot doesn't map when I define a CustomMapper

I have the following structure:
Controller (model classes) -> service -> (domain classes) repository.
This is what I do in the service layer when I have to persist something coming into the request body:
Map the model class (coming from the body request) into the domain class (Trying to use Orika)
Persist the domain class and after getting an OK from the DB
map the domain class saved in the DB into the model class (Trying to use Orika)
return back the response to the controller
This is what I have so far but it's not working:
#Component
public class CustomMapper extends ConfigurableMapper {
private MapperFactory factory = new DefaultMapperFactory.Builder().build();
#Override
protected void configure(MapperFactory factory) {
System.out.println("Spring boot mapper initializing.....");
factory.classMap(ModelSource.class, ModelDestination.class)
.byDefault()
.register();
}
I can see the message "Spring boot mapper initializing....." running spring boot so that means the component is loading OK.
#Autowired
private CustomMapper mapperFacade;
ModelDestination destination = mapperFacade.map(ModelSource.class, ModelDestination.class);
When I check all the destination fields, they are all null. What am I doing wrong? Thanks
Using the last Orika version 1.5.4. This fixed my issue:
.field("chain{}", "chain{}")

How to use a Spring bean as a Morphia entity listener?

The Morphia documentation provides an example on how #EntityListeners can be used to externalize life cycle methods to a separate class:
#EntityListeners(DigitalSigner.class)
public class BankAccount {
#Id
String id;
Date lastUpdated = new Date();
}
class DigitalSigner {
#PrePersist
void prePersist(final Object entity, final DBObject dbObject) {
dbObject.put("signature", sign(dbObject));
}
}
However, the documentation doesn't state how the class is instantiated. My guess is by calling the no-args constructor.
I need to call a Spring service from the entity listener or have the Spring service work as the listener. How can this be achieved (preferably without sticking the service into a static field)?
The functionality is provided by the ObjectFactory class, which can be set using MapperOptions.setObjectFactory. The custom ObjectFactory should return the appropriate Spring beans for the requested class types.

Update or SaveorUpdate in CRUDRespository, Is there any options available

I am trying to do CRUD operations with My Entity bean. CRUDRepository provide standard methods to find, delete and save but there is no generic method available like saveOrUpdate(Entity entity) that in turn calls Hibernate or HibernateTemplate sessions saveorUpdate() methods.
The way CRUDRepository provides this functionality is to
use like this
#Modifying
#Query("UPDATE Space c SET c.owner = :name WHERE c.id = :id")
Integer setNameForId(#Param("name") String name, #Param("id")
but this is not generic and needs to be written for complete form fields.
Please let me know if there is any way or i can get session of Hibernate or object of Spring HibernateTemplate to solve this issue.
The implementation of the method
<S extends T> S save(S entity)
from interface
CrudRepository<T, ID extends Serializable> extends Repository<T, ID>
automatically does what you want. If the entity is new it will call persist on the entity manager, otherwise it will call merge
The code looks like this:
public <S extends T> S save(S entity) {
if (entityInformation.isNew(entity)) {
em.persist(entity);
return entity;
} else {
return em.merge(entity);
}
}
and can be found here. Note that SimpleJpaRepository is the class that automatically implements CrudRepository in Spring Data JPA.
Therefore, there is no need to supply a custom saveOrUpdate() method. Spring Data JPA has you covered.
The issue is "i am using thymeleaf UI template and The Bean that i am trying to persist that is Form bean not Entity bean and that's why Spring boot is not saving it. Now i have to convert the entire Form bean into Entity bean with changed values and try to persist it." I got the solution for the specific problem i faced in my project, The solution is use #ModelAttribute to convert the form bean to entity.
#ModelAttribute("spaceSummary")
public SpaceSummary getSpaceSummary(int id){
return this.spaceSummaryService.getSpaceSummary(id);
}
and
#RequestMapping(value="/mgr/editSpace", method = RequestMethod.POST)
public ModelAndView editSpace(#ModelAttribute("spaceSummary") SpaceSummary
spaceSummary, BindingResult result, RedirectAttributes redirect, ModelAndView model) {
}

In a Spring example, how is a Validator object generated?

I am studying a spring exmaple. And I found the following code. I can't understand the construct function. A validator interface is passed to this function. How is this validator generated? Thanks in advance.
#Controller
#RequestMapping(value="/account")
public class AccountController {
private Map<Long, Account> accounts = new ConcurrentHashMap<Long, Account>();
private Validator validator;
#Autowired
public AccountController(Validator validator) {
this.validator = validator;
}
#RequestMapping(method=RequestMethod.POST)
public #ResponseBody Map<String, ? extends Object> create(#RequestBody Account account, HttpServletResponse response) {
Set<ConstraintViolation<Account>> failures = validator.validate(account);
if (!failures.isEmpty()) {
response.setStatus(HttpServletResponse.SC_BAD_REQUEST);
return validationMessages(failures);
} else {
accounts.put(account.assignId(), account);
return Collections.singletonMap("id", account.getId());
}
}
The validator can be any class that implements Springs Validator interface and is available in the current application context. By default Spring autowires by type. This means that every bean which implements the Validator interface can satisfy the constructor of AccountController. I don't know the exact example but there might be something like an AccountValidator bean available int the application context.
Be aware that this approach could cause problem if multiple validator beans are available in the application context.
See the Validation section in the spring documentation for details on the Validator interface.
When You use Autowired on constructor Spring looks for Validator implementation/
In this example Spring injects its default Validator implementation:
org.springframework.validation.beanvalidation.LocalValidatorFactoryBean
Here's more:
section: 5.7.2.1 Injecting a Validator
http://docs.spring.io/spring/docs/3.0.0.RC3/reference/html/ch05s07.html
There must be some concrete implementation of Validator.Without that it is not possible.
Further to support my answer see that it is being #Autowired.
Please post the link from which you are studying or check the source code for the presence of validaor class.
Also,check this link There is no concrete implementation by default.

Resources