required for input parameters on swagger - rest

when I use #RequestParam with required = true on rest and while testing this on swagger, it will be shown along with *required mark next to it.
#GetMapping(path = "/getinfo")
public ResponseEntity<?> getMyInfo(#RequestParam(value = "input", required = true) int input, other request parameters)
But now how can I achieve same on swagger if i have mapped url with object using #ModelAttribute .
#GetMapping(path = "/getinfo")
public ResponseEntity<?> getMyInfo(#ModelAttribute MyObject myObject)

You can try using the annotation #ApiParam
#GetMapping(path = "/getinfo")
public ResponseEntity<?> getMyInfo(#ModelAttribute("myObject") MyObject myObject)
Inside your MyObject class
public class MyObject {
private long id;
#ApiParam(name = "name", value = "Name is Mandatory", required = true)
private String name;
}
Now, name will be a *required field.

Related

Spring Data MongoDB not able to load reference collection (#DocumentReference)

In Spring data findAll method reference object is coming as null
I am using Reactive Mongo Repository
Ex Parent Object
#Data
#Document(collection = "country")
public class CountryBean {
#Id
private String id;
private String name;
}
Child Object
#Document(collection = "city")
public class CityBean {
#Id
private String id;
#Field(name = "name")
private String name;
#Field(name = "city_code")
private String cityCode;
#Field(name = "show_city")
private boolean showCity;
#DocumentReference(lazy = false)
private StateBean state;
}
Country Collection
State Collection (Here we can see the country Attribute)
But When trying to fetch from DB, I am getting country attribute as null. Tried both lazy true/false, but not getting country object along with state object.
#GetMapping("/get-all-state")
Flux<StateBean> allState() {
Flux<CountryBean> ct = countryRepository.findAll();
Flux<StateBean> bean= stateRepository.findByCountry(ct.blockFirst());
return bean;
}
[{"id":"6237a912850ceb6261998a53","name":"Bangalore","statecode":"39","country":null},{"id":"6237a94a850ceb6261998a55","name":"delhi","statecode":"39","country":null}]

Spring boot JPA - Custom Repository for multiple Entity

I've got some difficulties with my JPA Rest Project.
I have build my repositories for each of my entity (my tables in my database), and it works fine.
For example, a part of my entity "Personne" :
#Entity
public class Personne {
private Long id;
private String nom;
private String prenom;
private Date dateNaissance;
private String telDomicile;
private String telPortable;
private String telAutre;
private String telCommentaire;
private String fax;
private String mail;
private String commentaire;
private Timestamp dateSuppr;
private String sexe;
private Patient patientById;
private Adresse adresseByAdresseId;
#Id
#JsonProperty(value = "dataId")
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
}
And myRepository with a #Query :
#Transactional
#RepositoryRestResource(collectionResourceRel = "personne", path = "personne", excerptProjection = InlinePersonne.class)
public interface PersonneRepo extends JpaRepository<Personne, Long> {
#Query("from Personne p where p.nom = ?1 and p.prenom = ?2")
public Personne customRequest(String nom, String prenom);
}
My problem : the return result is always a type "Personne".
I would like to make a native request that sends me back an object, with customized properties.
Example of the wished return :
{object :
{name : String,
surname : String,
age : int },
adresse :{
city : String,
street : String
}
}
Is it possible to do that ?
I really need it because I have to make complex requests on many tables.
Thank you.
You could use interface-base projections:
First you create interfaces that reflect the fields you need:
interface PersonSummary {
String getName();
String getSurename();
int getAge();
AddressSummary getAddress();
interface AddressSummary {
String getCity();
String getStreet();
}
}
Then you indicate your custom query what interface it needs to extend and instantiate to populate the information:
public interface PersonneRepo extends JpaRepository<Personne, Long> {
// All your other abstract method
// Brand new query
#Query("Select p.name, p.surname, p.age, p.city, p.street from Personne p where p.nom = ?1 and p.prenom = ?2")
public PersonSummary customRequest(String nom, String prenom);
}
You would be receiving an object like this:
{
name : String,
surname : String,
age : int,
address :{
city : String,
street : String
}
}
You would need to test how flexible is this functionality in the terms of the composition complexity of the object you want to receive.

how to send post with MULTIPART_FORM_DATA with #RequestBody in restful service

I want to send #RequestBody as Post request to restful service.In #RequestBody I have id, title, aboutMe, and image file.I set produces = MediaType.MULTIPART_FORM_DATA_VALUEbut when i check in rest I get error that says
406 not acceptable .How can I solve it?
My controller:
#RequestMapping(value = "aboutMe", method = RequestMethod.POST, produces = MediaType.MULTIPART_FORM_DATA_VALUE)
public String saveAboutMe(#RequestBody Author author) {
authorService.saveAboutMe(author);
return "saved";
}
And entity
#Entity
#Table(name = "author")
public class Author {
#Id
#GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "HIBERNATE_SEQUENCE")
#SequenceGenerator(name = "HIBERNATE_SEQUENCE", sequenceName = "HIBERNATE_SEQUENCE", allocationSize = 1, initialValue = 1)
private int id;
#Column(name = "title")
private String title;
#JsonFormat(pattern = "yyyy-MM-dd HH:mm")
#Column(name = "dateOfAuthor")
#Temporal(TemporalType.TIMESTAMP)
private Date modifiedTime;
#Column(name = "aboutMe", length = 10000)
private String aboutMe;
#Column(name = "image")
#Lob
private Blob image;
}
Screenshot I get from rest error
You can not pass with #RequestBody and Blob object, image should be MultipartFile object. So for working code:
1) Inject SessionFactory into controller class or in any class where you want to convert Mulitpart to Blob object
#Autowired
private SessionFactory sessionFactory;
2) Changes for Controller class:
#RequestMapping(value = "aboutMe", method = RequestMethod.POST)
public String saveAboutMe(Author author,#RequestPart("image") MultipartFile imageFile) {
//Convert Multipart file into BLOB
try {
Blob image = Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(authorImage.getInputStream(),authorImage.getSize());
author.setImage(image);
} catch (HibernateException | IOException exception) {
log.error(exception.getMessage(),exception);
}
authorService.saveAboutMe(author);
return "saved";
}

need Spring Data JPA resource entry to make one many rest call

Using Spring Data jpa and Spring Data Rest I could able to get basic CRUD operations to work. But I am facing problem with one to many (owner -> car(s)) relationship. Can any one help me in this.
Owner.java
#Entity
#Table(name = "OWNER")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Owner implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "name")
private String name;
#Column(name = "age")
private Integer age;
#OneToMany(mappedBy = "owner")
#JsonIgnore
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Car> cars = new HashSet<>();
}
OwnerResource.java
#RestController
#RequestMapping("/api")
public class OwnerResource {
private final Logger log = LoggerFactory.getLogger(OwnerResource.class);
#Inject
private OwnerRepository ownerRepository;
#RequestMapping(value = "/owners",
method = RequestMethod.POST,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<Owner> create(#RequestBody Owner owner) throws URISyntaxException {
log.debug("REST request to save Owner : {}", owner);
if (owner.getId() != null) {
return ResponseEntity.badRequest().header("Failure", "A new owner cannot already have an ID").body(null);
}
Owner result = ownerRepository.save(owner);
return ResponseEntity.created(new URI("/api/owners/" + result.getId()))
.headers(HeaderUtil.createEntityCreationAlert("owner", result.getId().toString()))
.body(result);
}
#RequestMapping(value = "/owners",
method = RequestMethod.PUT,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<Owner> update(#RequestBody Owner owner) throws URISyntaxException {
log.debug("REST request to update Owner : {}", owner);
if (owner.getId() == null) {
return create(owner);
}
Owner result = ownerRepository.save(owner);
return ResponseEntity.ok()
.headers(HeaderUtil.createEntityUpdateAlert("owner", owner.getId().toString()))
.body(result);
}
#RequestMapping(value = "/owners",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<List<Owner>> getAll(#RequestParam(value = "page" , required = false) Integer offset,
#RequestParam(value = "per_page", required = false) Integer limit)
throws URISyntaxException {
Page<Owner> page = ownerRepository.findAll(PaginationUtil.generatePageRequest(offset, limit));
HttpHeaders headers = PaginationUtil.generatePaginationHttpHeaders(page, "/api/owners", offset, limit);
return new ResponseEntity<>(page.getContent(), headers, HttpStatus.OK);
}
#RequestMapping(value = "/owners/{id}",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<Owner> get(#PathVariable Long id) {
log.debug("REST request to get Owner : {}", id);
return Optional.ofNullable(ownerRepository.findOne(id))
.map(owner -> new ResponseEntity<>(
owner,
HttpStatus.OK))
.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
}
OwnerRepository.java
/**
* Spring Data JPA repository for the Owner entity.
*/
public interface OwnerRepository extends JpaRepository<Owner,Long> {
}
The basic crud operation is working fine for Owner. But now I need to get all cars of a particular owner for that I need to add one rest call entry in OwnerResource.java and a method entry in OwneRepository.java. I tried different ways but getting many errors and is not working. The following is what I tried.
In OwnerRepository.java
Owner findAllByOwnerId(Long id);//But eclipse shows error here for this method
In OwnerResource.java
//Get All Cars
#RequestMapping(value = "/{id}/cars",
method = RequestMethod.GET,
produces = MediaType.APPLICATION_JSON_VALUE)
#Timed
public ResponseEntity<Owner> getAll(#PathVariable Long id) {
log.debug("REST request to get All Cars of the Owner : {}", id);
return Optional.ofNullable(ownerRepository.findAllByOwnerId(id))
.map(owner -> new ResponseEntity<>(
owner,
HttpStatus.OK))
.orElse(new ResponseEntity<>(HttpStatus.NOT_FOUND));
}
But these two changes are not working out. I am beginner to spring data jpa and spring data rest. Can any one help me in correcting these two so that I can get all cars of the owner.
I believe it shows an error because the findAll returns a different type of object: List, Page, etc...
Try this:
List<Owner> findAllByOwnerId(#Param("id") Long id);
That will return you a list of objects. If you want to return with pagination, than you need this instead:
Page<Owner> findAllByOwnerId(#Param("id") Long id, Pageable pageable);
I hope this helps, let me know how it works for you.

Copy Entity ID at persist time

I want to copy the entity's UUID, generated at run time to another field.
The entity id is generated via the code described bellow:
package eclipselink.example;
public class UUIDSequence extends Sequence implements SessionCustomizer {
public UUIDSequence() {
super();
}
public UUIDSequence(String name) {
super(name);
}
#Override
public Object getGeneratedValue(Accessor accessor,
AbstractSession writeSession, String seqName) {
return UUID.randomUUID().toString().toUpperCase();
}
...
public void customize(Session session) throws Exception {
UUIDSequence sequence = new UUIDSequence("system-uuid");
session.getLogin().addSequence(sequence);
}
}
Persitence.xml:
property name="eclipselink.session.customizer" value="eclipselink.example.UUIDSequence"
The entity:
public abstract class MyEntity{
private String id;
private String idCopy;
#Id
#Basic(optional = false)
#GeneratedValue(generator="system-uuid")
#XmlElement(name = "ID")
public String getId() {
return id;
}
}
How can I instruct JPA (Eclipse-link) to copy the UUID generated at runtime to idCopy field as well?
I'm not 100% sure this will work (I don't know if EclipseLink calls the setter or assigns the field directly), but give this a try:
public abstract class MyEntity{
private String id;
private String idCopy;
#Id
#Basic(optional = false)
#GeneratedValue(generator="system-uuid")
#XmlElement(name = "ID")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
this.idCopy = id;
// or
// this.setIdCopy(id);
}
}