I have drop-down of Entity "BusinessPartner".
I have all my entities ID's as String and customized "org.hibernate.id.UUIDGenerator" to add relavent prefix to my ID's ex: "BPID_04a3e35b-12b3-447f-a982-338739e537f1"
i am getting the following exception when i try to navigate to the page which contain the drop-down of "BusinessPartner" entity.
Searched all over the internet for solution, let me know if anyone have any clue. I have pointed out where exactly i am getting exception in below snippet.
Java Version: 1.8
Spring Boot Version: 1.5.10.RELEASE
Entity Order:
#Entity
#Table(name = Order.TABLE_NAME)
public class Order extends Model implements Serializable {
#Enumerated(EnumType.STRING)
#Column(name = DOCUMENT_TYPE)
private DocumentType documentType;
#Column(name = DOCUMENT_NUMBER, updatable = false)
private String documentNumber;
#Column(name = ORDER_DESCRIPTION)
#NotEmpty
private String orderDescription;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = COL_OTHER_PARTY_ID, nullable = false)
private BusinessPartner otherParty;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = COL_AUTHORITY_BUSINESS_PARTNER_ID, nullable = false)
private BusinessPartner authority;
}
Entity BusinessPartner:
#Entity
#Table(name = BusinessPartner.ENTITY_NAME)
public class BusinessPartner extends Model {
#Column(name = NAME)
private String name;
#Column(name = EMAIL)
private String email;
// Getters and Setters omitted for simplicity
}
Parent Entity:
#MappedSuperclass
public class Model {
public static final String ID = "id";
public static final String CREATED_AT = "createdAt";
public static final String UPDATED_AT = "updatedAt";
#Id
#GeneratedValue(generator = "uuid")
#GenericGenerator(name = "uuid", strategy = "com.emisha.database.Generators.IDGenerator")
#Column(name = ID)
private String id;
#Version
private Long version;
#Column(name = CREATED_AT)
private Date createdAt;
#Column(name = UPDATED_AT)
private Date updatedAt;
public Model() {
// Empty Constructor
}
/* DEFINED METHODS */
#PrePersist
protected void onCreate() {
updatedAt = createdAt = new Date();
}
#PreUpdate
protected void onUpdates() {
updatedAt = new Date();
}
// GETTERS & SETTERS
}
Controller method that populates businessPartners:
#Controller
#Secured(SecurityUtil.MANAGE_PURCHASEORDER)
#SessionAttributes("order")
#RequestMapping("Orders")
public class OrderController extends EmishaAdminBaseController {
//.........
#RequestMapping(value = "/{documentType}/form/{id}", method = RequestMethod.GET)
public String getOrder(#PathVariable("documentType") String documentType, #PathVariable("id") String id, Model model, HttpServletRequest request, RedirectAttributes redirectAttributes) {
String view = "PurchaseOrder/form";
if (documentType.equalsIgnoreCase("SalesOrder")) {
view = "SalesOrder/form";
}
User user = Objects.requireNonNull(getCurrentUser()).getUser();
// Mapped Product Data
Order order;
// Default Form control data
String action = request.getContextPath() + "/Orders/" + documentType + "/form/" + id;
String mode = "EDIT_ORDER";
logger.debug("Default mode set to: " + mode + "\n" + "Default action set to: " + action);
if (documentType.equalsIgnoreCase("CreateSalesOrder")) {
action = request.getContextPath() + "/Orders/SalesOrder/form/" + id;
view = "SalesOrder/form";
if (id != null && !id.isEmpty()) {
Order purchaseOrder = orderService.getOrder(id);
order = OrderHelper.convertToSalesOrder(purchaseOrder);
} else {
redirectAttributes.addFlashAttribute("error", "Invalid Purchase Order.");
return "redirect:/Sales/Quotations";
}
} else {
if (id.equals("new")) {
mode = "CREATE_ORDER";
// Create new instance for creating new Procurement Requisition.
order = new Order();
if (documentType.toLowerCase().equals("PurchaseOrder".toLowerCase())) {
// Set default statuses for new Procurement Requisition
order.setStatus(Status.DRAFT);
order.setPublicationType(PublicationType.RESTRICTED);
// Set document type to Purchase Requirement.
order.setDocumentType(DocumentType.PURCHASE_ORDER);
// Set initial processing status to PR Created.
order.setProcessingStatus(ProcessingStatus.PO_CREATED);
} else if (documentType.toLowerCase().equals("SalesOrder".toLowerCase())) {
// Set default statuses for new RFQ ProcurementRequisition
order.setStatus(Status.DRAFT);
order.setPublicationType(PublicationType.RESTRICTED);
// Set document type to Request for Quotation.
order.setDocumentType(DocumentType.SALES_ORDER);
// Set initial processing status to REF Created.
order.setProcessingStatus(ProcessingStatus.SO_CREATED);
}
logger.debug("Mode set to: " + mode + "\n" + "Action set to: " + action);
} else {
order = orderService.getOrder(id);
}
}
addAllDropDowns(model, user);
// Add business data to model
model.addAttribute("order", order);
// Add form control data to model
model.addAttribute("action", action);
model.addAttribute("mode", mode);
return view;
}
//.........
private void addAllDropDowns(Model model, User user) {
// Add dropdown data to model
/* Products drop down */
List<Product> products = new ArrayList<>();
products = productService.getProducts(user.getBusinessPartner());
model.addAttribute("products", products);
/* Unit of Measurements drop down */
List<UnitOfMeasurement> unitOfMeasurements = new ArrayList<>();
unitOfMeasurements = unitOfMeasurementService.getAllUnitOfMeasurements();
model.addAttribute("unitOfMeasurements", unitOfMeasurements);
/* Users drop down */
List<User> users = new ArrayList<>();
users = userService.getUsersWhere(user.getBusinessPartner());
model.addAttribute("users", users);
/* Vendors drop down */
List<BusinessPartner> vendors = new ArrayList<>();
vendors = businessPartnerService.getVendors(user.getBusinessPartner());
model.addAttribute("vendors", vendors);
}
}
Thyemeleaf Drop-down in my view.html file:
<label>Customer</label>
<select th:if="*{order?.quotation ==null}" class="form-control"
th:field="*{otherParty}"
data-placeholder="Select an option" data-allow-clear="true"
tabindex="-1"
style="width: 250px; background-color: #d2e1f3;">
<option value="">Select</option>
<option th:each="vendor,istat : ${vendors}"
th:value="${vendor?.id}" //<---- java.lang.NumberFormatException: For input string: "BPID_04a3e35b-12b3-447f-a982-338739e537f1"
th:text="${vendor?.name}">
Manufacturer
</option>
</select>
Here is the Stack trace:
java.lang.NumberFormatException: For input string: "BPID_04a3e35b-12b3-447f-a982-338739e537f1"
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:1.8.0_152]
at java.lang.Integer.parseInt(Integer.java:580) ~[na:1.8.0_152]
at java.lang.Integer.valueOf(Integer.java:766) ~[na:1.8.0_152]
at org.springframework.util.NumberUtils.parseNumber(NumberUtils.java:208) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]...
Related
I have 2 entitied (Post and FileUploads), the Post entity is responsible for a user to create an advert/post and the FileUploads entity is responsible for handling image uploads together with a post. (A post can have multiple FileUploads/Images associated with it).
The issue is that I get an error:
Column 'post_id' cannot be null
I'm unsure as to what's causing it, The PK in the FileUpload entity is a String and the Post entity PK is a Long, I don't know if that could be the cause?
I am auto-generating my Post PK as well.
FileUpload.java (Entity)
#Entity
#Table(name="file_upload")
public class FileUpload {
#Id
#GenericGenerator(name = "uuid", strategy = "uuid2")
#GeneratedValue(generator = "uuid")
#Column(name="id")
private String fileId;
private int imageCount;
private String name;
private String type;
private String fileUploader;
#Lob
private byte[] data;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="post_id", nullable = false)
private Post post;
public FileUpload() {
}
public FileUpload(int imageCount, String name, String type, String fileUploader, byte[] data, Post post) {
this.imageCount = imageCount;
this.name = name;
this.type = type;
this.fileUploader = fileUploader;
this.data = data;
this.post = post;
}
Post.java (Entity)
Left out the other fields since i have a quite a bit
#Entity
public class Post {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotBlank(message = "Required")
#Size(max=45, message = "Maximum of 45 letters")
#Column(unique = true)
private String title;
private String postCreatorEmail;
private String postCreator;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "post")
private List<FileUpload> fileUploads = new ArrayList<>();
public Post() {
}
FileServiceImpl.java
Method to store images
#Service
public class FileUploadServiceImpl implements FileUploadService{
#Autowired
private FileUploadRepository fileUploadRepository;
#Autowired
private PostRepository postRepository;
private int imageCount;
#Override
public FileUpload uploadPostImage(MultipartFile file, String emailAddress) throws IOException {
Post thePost = postRepository.findPostByPostCreatorEmail(emailAddress);
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
FileUpload fileDB = new FileUpload(++imageCount, fileName, file.getContentType(), emailAddress, file.getBytes(), thePost);
return fileUploadRepository.save(fileDB);
}
}
PostServiceImpl.java
#Service
public class PostServiceImpl implements PostService{
#Autowired
private PostRepository postRepository;
#Autowired
private UserRepository userRepository;
#Autowired
private FileUploadServiceImpl fileUploadService;
private int count;
#Override
public Post createOrUpdatePost(String post, String emailAddress){
// Removed update code
Post thePost = new Post();
try {
User user = userRepository.findUserByEmailAddress(emailAddress);
ObjectMapper objectMapper = new ObjectMapper();
thePost = objectMapper.readValue(post, Post.class);
user.setTotalAds(++count);
thePost.setPostCreator(user.getFullName());
thePost.setPostCreatorEmail(emailAddress);
thePost.setFileUploads(thePost.getFileUploads());
thePost.setUser(user);
userRepository.save(user);
return postRepository.save(thePost);
// The ad with the same title already exists - go to catch block
} catch (Exception e) {
throw new PostAlreadyExistsException("Post with title " + thePost.getTitle() + " already exists");
}
}
}
PostController.java (Only adding the handler method)
#PostMapping("/create")
public ResponseEntity<?> createPost(#RequestPart("file") MultipartFile file, #Valid #RequestPart String post, BindingResult result, Principal principal) {
ResponseEntity<?> errorMap = errorValidationService.validationService(result);
if(errorMap != null) return errorMap;
String message = "";
try {
fileUploadService.uploadPostImage(file, principal.getName());
postService.createOrUpdatePost(post, principal.getName());
message = "Uploaded the file successfully: " + file.getOriginalFilename();
return ResponseEntity.status(HttpStatus.OK).body(new ApiResponse(message, true));
} catch (Exception e) {
message = "Could not upload the file: " + file.getOriginalFilename() + "!";
return ResponseEntity.status(HttpStatus.BAD_REQUEST).body(new ApiResponse(message, false));
}
}
Postman results
Console output
Post DDL MySQL
FileUpload DDL MySQL
Try to add modify your uploadPostImage to this code:
#Override
public FileUpload uploadPostImage(MultipartFile file, String emailAddress) throws IOException {
Post thePost = postRepository.findPostByPostCreatorEmail(emailAddress);
// new part:
if (thePost == null) {
throw new RuntimeException("No post found yet for eMail-Address '" + emailAddress + "' to store images for!");
}
String fileName = StringUtils.cleanPath(file.getOriginalFilename());
FileUpload fileDB = new FileUpload(++imageCount, fileName, file.getContentType(), emailAddress, file.getBytes(), thePost);
return fileUploadRepository.save(fileDB);
}
I need that every time I list a portfolio it returns all the images that exist in that specific portfolio
I can list 1 by 1 via ID but when I send my endpoint to list all photos belonging to the ID of a specific portfolio it only returns me null
Photo Class
#Entity
public class Foto {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
private String nomeArquivo;
#ManyToOne(cascade = CascadeType.MERGE)
private Perfil autonomo;
#Column(length = 5_000_000)
private byte[] fotoByte;
private String tipoArquivo;
}//Getters and Setters
AutonomoService
#Autowired
FotosRepository fotosRepository;
#Autowired
PerfisRepository perfisRepository;
public List<byte[]> portfolio(int id){
if (perfisRepository.existsById(id)) {
return fotosRepository.findAllByAutonomoId(id).stream().map(f-> f.getFotoByte()).collect(Collectors.toList());
}
else {
return null;
}
} //Getters and Setters
Controller
#GetMapping("/portfolio/fotos/{id}")
public ResponseEntity<List<byte[]>> getPortfolioAutonomo(#PathVariable int id) throws IOException {
List<byte[]> result = autonomoService.portfolio(id);
return ResponseEntity.status(200).body(result);
}
And this is the way I can get 1 photo by its id
#GetMapping("/portfolio/{id}")
public ResponseEntity getPortfolio(#PathVariable int id){
Optional<Foto> anexoOptional = fotosRepository.findById(id);
if (anexoOptional.isPresent()) {
Foto anexo = anexoOptional.get();
return ResponseEntity.status(200)
.header("content-type", anexo.getTipoArquivo())
.header("content-disposition", "filename=" + anexo.getNomeArquivo())
.body(anexo.getFotoByte());
} else {
return ResponseEntity.status(404).build();
}
}
Instead of
return fotosRepository.findAllByAutonomoId(id).stream().map(f-> f.getFotoByte()).collect(Collectors.toList());
Can you try with
return fotosRepository.findAllById(id).stream().map(f-> f.getFotoByte()).collect(Collectors.toList());
If still this is not working, better to go with #Query implemention.
I'm working with Spring, hibernate and MySql but I have some problem with seralization of query result.
First in my entity I added #JsonManagedReference on Set structure (#OneToMany side) and #JsonBackReference on single object reference (#ManyToOne side) and it works but I wasn't be able to retrieve all needed information (for example #ManyToOne reference).
So i swapping #JsonBackReference on set structure and #JsonManagedReference on single object but I retrieve
No serializer found for class org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer and no properties discovered to create BeanSerializer (to avoid exception, disable SerializationFeature.FAIL_ON_EMPTY_BEANS) ) (through reference chain: com.model.tablesField.TableUI["data"]->java.util.ArrayList[0]->com.domain.Car["carType"]->com.domain.CarType_$$_jvst744_f["handler"])
I tried also with #JsonIgnore on Set structure but it doesn't work for the same issues.
This is my spring configuration
private Properties getHibernateProperties() {
Properties properties = new Properties();
properties.put(PROPERTY_NAME_HIBERNATE_DIALECT, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_DIALECT));
// properties.put(PROPERTY_NAME_HIBERNATE_SHOW_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_SHOW_SQL));
properties.put(PROPERTY_NAME_HIBERNATE_FORMAT_SQL, env.getRequiredProperty(PROPERTY_NAME_HIBERNATE_FORMAT_SQL));
properties.put("hibernate.enable_lazy_load_no_trans",true);
return properties;
and this is part of one of my several entities:
/**
* Car generated by hbm2java
*/
#Entity
#Table(name = "car", catalog = "ATS")
public class Car implements java.io.Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private Integer idCar;
#JsonManagedReference
private CarType carType;
#JsonManagedReference
private Fleet fleet;
private String id;
private int initialKm;
private String carChassis;
private String note;
#JsonBackReference
private Set<Acquisition> acquisitions = new HashSet<Acquisition>(0);
public Car() {
}
public Car(CarType carType, Fleet fleet, int initialKm, String carChassis) {
this.carType = carType;
this.fleet = fleet;
this.initialKm = initialKm;
this.carChassis = carChassis;
}
public Car(CarType carType, Fleet fleet, String id, int initialKm, String carChassis, String note,
Set<Acquisition> acquisitions) {
this.carType = carType;
this.fleet = fleet;
this.id = id;
this.initialKm = initialKm;
this.carChassis = carChassis;
this.note = note;
this.acquisitions = acquisitions;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "id_car", unique = true, nullable = false)
public Integer getIdCar() {
return this.idCar;
}
public void setIdCar(Integer idCar) {
this.idCar = idCar;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_carType", nullable = false)
public CarType getCarType() {
return this.carType;
}
public void setCarType(CarType carType) {
this.carType = carType;
}
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "id_fleet", nullable = false)
public Fleet getFleet() {
return this.fleet;
}
public void setFleet(Fleet fleet) {
this.fleet = fleet;
}
#Column(name = "id", length = 5)
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
#Column(name = "initialKm", nullable = false)
public int getInitialKm() {
return this.initialKm;
}
public void setInitialKm(int initialKm) {
this.initialKm = initialKm;
}
#Column(name = "carChassis", nullable = false, length = 20)
public String getCarChassis() {
return this.carChassis;
}
public void setCarChassis(String carChassis) {
this.carChassis = carChassis;
}
#Column(name = "note", length = 100)
public String getNote() {
return this.note;
}
public void setNote(String note) {
this.note = note;
}
#OneToMany(fetch = FetchType.LAZY, mappedBy = "car")
public Set<Acquisition> getAcquisitions() {
return this.acquisitions;
}
public void setAcquisitions(Set<Acquisition> acquisitions) {
this.acquisitions = acquisitions;
}
}
one method that uses the query:
#Override
#RequestMapping(value = { "/cars/{idFleet}"}, method = RequestMethod.GET)
public #ResponseBody TableUI getCars(#PathVariable int idFleet) {
TableUI ajaxCall=new TableUI();
try {
ajaxCall.setData(fleetAndCarService.findCarsByIdFleet(idFleet));
return ajaxCall;
} catch (QueryException e) {
ErrorResponse errorResponse= ErrorResponseBuilder.buildErrorResponse(e);
LOG.error("Threw exception in FleetAndCarControllerImpl::addCar :" + errorResponse.getStacktrace());
return ajaxCall;
}
}
two class for the query:
public interface DefRdiRepository extends JpaRepository<DefRdi, Integer>{
//#Query("SELECT CASE WHEN COUNT(c) > 0 THEN true ELSE false END FROM DefRdi c WHERE c.parName = ?1 AND c.description= ?2")
//Boolean existsByParNameAndDescription(String parName, String description);
//Query method of spring, I put findBy and then the key of research
DefRdi findByParNameAndDescription(String parName, String description);
}
public interface CarRepository extends JpaRepository<Car, Integer>, CarRepositoryCustom {
//Query method of spring, I put findBy and then the key of research
List<Car> findByFleetIdFleet(int idFleet);
}
Where is my error? I don't want Set object but only the single reference. The problem is only when I serialize. Thanks
UPDATE:
I use #JSonIgnore on all set collectionts and Eager instead lazy ad all works fine, but is there a way to retrieve all the information only when I want, for example having two different query?
So it doesn't work
#Override
#Transactional
public List<Car> findByFleetIdFleet(int idFleet) {
List<Car> carList= carRepository.findByFleetIdFleet(idFleet);
for (Car car:carList){
Hibernate.initialize(car.getCarType());
Hibernate.initialize(car.getFleet());
}
return carList;
// return carRepository.findByFleetIdFleet(idFleet);
}
All collections need to be fetched eagerly when loading them from data base, in order to get serialized by Spring. Make sure you fetch them eagerly (e.g. FetchMode.JOIN). You could also swap #JsonManagedReference from wanted fields with #JsonIgnore to black listed fields, Spring automatically serialises every field without annotation.
Update:
Changing the data repository to something like that should work, I am not sure it compiles, but I think you will get the point:
#EntityGraph(value = "some.entity.graph", type = EntityGraph.EntityGraphType.FETCH)
#Query(
value = "SELECT c FROM Car c INNER JOIN FETCH c.acquisitions WHERE c.id = :idFleet"
)
public interface CarRepository extends JpaRepository<Car, Integer>, CarRepositoryCustom {
//Query method of spring, I put findBy and then the key of research
List<Car> findByFleetIdFleet(int idFleet);
}
For more information look at this post and read the official documentation.
Workaround:
There seems to be a workaround, however fetching those collections eager like shown above should have a positive performance impact, since there is no need for loading proxies afterwards. Also no open transactions are needed at controller level.
Dear spring Java professionals
please help me out in this :
I have a custom service in spring and I dont have any errors on my wildfly server when i run it . but when I do the below update request i am getting 400 bad request though im sending the format as specified in my controller
inside my controller :
#RequestMapping(value = "/user/updatefilters/{Id}", method = RequestMethod.POST)
public Response updateFilter(#PathVariable("Id") Long Id, #RequestBody #Valid Filter Filter) {
FilterService.updateFilter(Id, Filter);
HashMap<String, Object> response = new HashMap<>();
response.put("messages", null);
response.put("success", Boolean.valueOf(true));
return Response.instance().friendlyName("filter-updated").object(response).statusCode(HttpStatus.OK);
}
inside my service file :
public void updateFilter(Long Id,Filter Filter) {
List<Filter> currentFilter = FilterRepo.getFilters(Id, Filter.getFilterId().longValue(),null);
currentFilter.get(0).setLabel(Filter.getLabel());
FilterRepo.save(currentFilter.get(0));
for (FilterField FilterField : Filter.getFilterFields()) {
FilterField currentFilterField = FilterFieldRepo.getFilterField(FilterField.getfieldId());
if (currentFilterField != null) {
currentFilterField.setfield(FilterField.getfield());
currentFilterField.setTypeId(FilterField.getTypeId());
FilterFieldRepo.save(currentFilterField);
}
}
}
inside my repository :
public List<Filter> getFilterList(Long Id, String type) {
List<Filter> FilterField = FilterFieldRepo.getFilterFields(Id,type);
return FilterField;
}
public void updateFilter(Long Id,Filter Filter) {
List<Filter> currentFilter = FilterRepo.getFilters(Id, Filter.getFilterId().longValue(),null);
currentFilter.get(0).setLabel(Filter.getLabel());
FilterRepo.save(currentFilter.get(0));
for (FilterField FilterField : Filter.getFilterFields()) {
FilterField currentFilterField = FilterFieldRepo.getFilterField(FilterField.getfieldId());
if (currentFilterField != null) {
currentFilterField.setfield(FilterField.getfield());
currentFilterField.setTypeId(FilterField.getTypeId());
FilterFieldRepo.save(currentFilterField);
}
}
}
Please note that inside my entity I added a transient list like this :
#Transient
private List<FilterField> filterFields;
updated :
this is my Filter class i generated the crud in netbeans but added the transuent list manually:
#Entity
#Table(schema="hitmeister",name = "filters")
#NamedQueries({
#NamedQuery(name = "Filter.findAll", query = "SELECT s FROM Filter s"),
#NamedQuery(name = "Filter.findByFilterId", query = "SELECT s FROM Filter s WHERE s.filterId = :filterId"),
#NamedQuery(name = "Filter.findById", query = "SELECT s FROM Filter s WHERE s.Id = :Id"),
#NamedQuery(name = "Filter.findByLabel", query = "SELECT s FROM Filter s WHERE s.label = :label"),
#NamedQuery(name = "Filter.findByInsertionDate", query = "SELECT s FROM Filter s WHERE s.insertionDate = :insertionDate"),
#NamedQuery(name = "Filter.findByIsActive", query = "SELECT s FROM Filter s WHERE s.isActive = :isActive"),
#NamedQuery(name = "Filter.findByType", query = "SELECT s FROM Filter s WHERE s.type = :type")})
public class Filter implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "filter_id")
private Integer filterId;
#Basic(optional = false)
#NotNull
#Column(name = "id")
private int Id;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 500)
#Column(name = "label")
private String label;
#Basic(optional = true)
#Column(name = "insertion_date")
#Temporal(TemporalType.TIMESTAMP)
private Date insertionDate;
#Column(name = "is_active")
private Boolean isActive;
#Basic(optional = false)
#NotNull
#Size(min = 1, max = 20)
#Column(name = "type")
private String type;
#Transient
private List<FilterField> filterFields;
public Filter() {
}
public Filter(Integer filterId) {
this.filterId = filterId;
}
public Filter(Integer filterId, int Id, String label, Date insertionDate, String type) {
this.filterId = filterId;
this.Id = Id;
this.label = label;
this.insertionDate = insertionDate;
this.type = type;
}
public Integer getFilterId() {
return filterId;
}
public void setFilterId(Integer filterId) {
this.filterId = filterId;
}
public int getId() {
return Id;
}
public void setuserId(int Id) {
this.userId = userId;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public Date getInsertionDate() {
return insertionDate;
}
public void setInsertionDate(Date insertionDate) {
this.insertionDate = insertionDate;
}
public Boolean getIsActive() {
return isActive;
}
public void setIsActive(Boolean isActive) {
this.isActive = isActive;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
#Override
public int hashCode() {
int hash = 0;
hash += (filterId != null ? filterId.hashCode() : 0);
return hash;
}
#Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof Filter)) {
return false;
}
Filter other = (Filter) object;
if ((this.filterId == null && other.filterId != null) || (this.filterId != null && !this.filterId.equals(other.filterId))) {
return false;
}
return true;
}
#Override
public String toString() {
return " Filter #"+ filterId ;
}
public List<FilterField> getFilterFields() {
return filterFields;
}
public void setFilterFields(List<FilterField> filterFields) {
this.filterFields = filterFields;
}
}
If you need my entity code i can post it as well
Thanks In advance !
My first recommendation: (OP tried and it didn't work, she was sending POST request)
Change your mapping as below and I think you should be fine. Request from browser address bar is a GET request.
As you can see below, HTTP 400 comes when server is unable to understand the request client is sending, and in your case you are sending GET but server has nothing for GET but for POST, so 400.
W3C HTTP 400
10.4.1 400 Bad Request
The request could not be understood by the server due to malformed
syntax. The client SHOULD NOT repeat the request without
modifications.
Code fix:
#RequestMapping(value = "/user/updatefilters/{Id}", method = RequestMethod.GET)
My second recommendation:
I am not Spring expert but here are my 2 cents you can try based on the JSON object you have provided and your Filter mapping - (1.) Change userId to Id, (2.) Have insertionDate as NULL, instead of an empty string.
Make sure your JSON string variables are mapped case-sensitively with your Filter class mapping, and their values are compatible with reference types.
Either your request format is not what Spring expects, or one of the Filter validations is failing. Add a org.springframework.validation.Errors argument and dump the values to find out what validations failed.
public Response updateFilter(#PathVariable("Id") Long Id, #RequestBody #Valid Filter Filter, Errors filterErrors) {
You can sniff the actual traffic using curl or a network monitoring tool to make sure the HTTP transaction is really what you think it is.
EDIT: Having looked at the JSON in one of your comments, I think this is going to turn out to be upper/lower case in your JSON field names. Either change "Id" to "id" and "FilterId" to "filterId", or annotate the Filter fields with #XmlElement(name = "Id") and #XmlElement(name = "FilterId"). Java Bean property names are case sensitive.
EDIT 2: Filter.setuserId(int Id) is broken as well. You need a setId() method for deserializing the bean, and you need to change the method so it stores the passed argument instead of just setting userId to itself.
I'm learning Hibernate and Play framework (also add Java into account...). I'm having problems saving this kind of entity
#Entity
#Table(name="users")
public class User extends Model {
#Required
public String username;
#Column(name="user_displayname",nullable=true)
public String displayname;
#Password
public String user_password;
#Email
#Column(name="user_email",nullable=false,unique=true)
public String user_email;
public String user_salt;
public Date user_joindate;
#ManyToOne
#JoinTable(name="users_meta")
public UserMeta userdata;
#Required
public boolean user_isActive;
#OneToOne(targetEntity=UserPhotos.class,cascade=CascadeType.ALL)
#JoinColumn(name="id",referencedColumnName="userID")
public UserPhotos userPhoto;
#ManyToMany(cascade=CascadeType.ALL)
#JoinTable(name="links_rol2user")
public List<Rol> rol;
public User (String username, models.Pass password, String user_email) {
this.username = username;
this.user_password = password.getHashedPassword();
this.user_salt = password.getUserHash();
this.user_email = user_email;
this.user_joindate = new Date();
this.user_isActive = false;
}
This is my code when I'm registering a user
// check if the validation has errors
if(validation.hasErrors()) {
params.flash(); // add http parameters to the flash scope
validation.keep(); // keep the errors for the next request
register();
} else {
Cache.delete(uuid);
Pass pass = new Pass(password,new Date().toString());
User newUser = new User(firstName, pass, email);
UserMeta utest = new UserMeta(newUser.id);
utest.setUserTownID(pueblos);
newUser.setUserMeta(utest);
newUser.save();
Logger.info("NewUser ID : %s", newUser.getId());
// UserMeta userInfo = new UserMeta(newUser.getId());
// userInfo.setUserTownID(pueblos);
// userInfo.save();
// TODO salvar foto a null
// Confirmation left
Cache.set("thankyou", "alright!", "3mn");
thankyou();
}
I'm trying to save the userMeta, it does creates a new record when I set the userMeta object into newUser (not visible right now), but it doesn't insert the new ID created in newUser.
What kind of relation do I need? before I tweaked the code as it is now, it was a OneToOne relationship, worked quite well, but now when I was completing the register functions it kinda hit me that I needed to save userMeta object too..
If you need more info let me know, I don't know if I explained it well or not, just trying to get the hang of how Hibernate do relations, etc.
Adding UserMeta:
*/
#Entity
#Table(name="users_meta")
public class UserMeta extends Model {
#Lob
#Column(name="userBio")
public String userBio;
#Column(name="userPhotoID",nullable=true)
public Long userPhotoID = null;
#Column(name="userRoleID", nullable=false)
public Long userRoleID = 2L;
#Lob
public String userDescription;
#Column(name="userViews", nullable=false)
public Long userViews = 0L;
#Column(name="userFavoriteCount", nullable=false)
public Long userFavoriteCount = 0L;
#Column(name="userTotalComments", nullable=false)
public Long userTotalComments = 0L;
#Column(name="userTotalUploadedVideos", nullable=false)
public Long userTotalUploadedVideos = 0L;
public Long userTownID;
public Long userID;
public UserMeta() {}
public UserMeta(Long userid) {
this.userBio = "El usuario no ha escrito nada todavia!";
this.userDescription = "El usuario todavia no se ha describido!";
this.userID = userid;
}
public Long getUserTownID() {
return userTownID;
}
public void setUserTownID(Long userTownID) {
this.userTownID = userTownID;
}
}
// pass model
public class Pass {
protected String hashed;
protected String userHash;
public Pass(String passwordToHash, String salt) {
StringBuffer passSalt = new StringBuffer(passwordToHash);
this.userHash = DigestUtils.md5Hex(salt);
passSalt.append(this.userHash);
passSalt.append(Play.configuration.getProperty("application.passwordSalt"));
this.hashed = DigestUtils.sha512Hex(passSalt.toString());
}
public String getHashedPassword() {
return this.hashed;
}
public String getUserHash() {
return this.userHash;
}
}
There seems to be a lot going on there! But from what I can tell, you problem is with the id that you are passing into the UserMeta.
As you are extending Model, the id is being generated by the Model class. However, this is not set until after the entity is saved to the database (as the id is auto-generated by the database).
Therefore, because you are passing the id into the UserMeta before the User object is saved, the value of id will be null.
If you can save the User object before you create your UserMeta object, your code should work.