Insert images in database - spring-boot

I'm making a real estate app in spring boot - thymeleaf and I really need to ask you how to store images. I was thinking about making a table just for images and anotate it manyToOne, and insert it into Property entity because one property can have 10,15,20 images and that is the part I know how to do.
But I'm not sure how to handle the rest of the code. How to make file upload in the /add method?
And also howadd and show them in thymeleaf?
This is my /properties/add method without the option of inserting images:
#RequestMapping("/add")
public String add(Model theModel) {
Property theProperty = new Property();
User theUser = new User();
theProperty.setUser(theUser);
List<User> userList = userService.findAll();
Address theAddress = new Address();
theProperty.setAddress(theAddress);
List<Address> addressList = addressService.findAll();
theModel.addAttribute("property", theProperty);
theModel.addAttribute("user", userList);
theModel.addAttribute("address", addressList);
return "properties/property-form";
}
I don't expect you to type it but maybe somebody know the most similar project

I don't think you wanna store the images directly to the database but having a table as a reference to the image itself.
You can do it the same way as you are doing with the userList.
theProperty.addAttribute("images", imageList);

Related

Spring #Transactional is not commited. Neo4J

I have an entity User that has relationship WORKS_FOR with an entity Organization. Organization has relationship HAS_EMPLOYEE with all users that are in and a relationship HAS_ANCHOR, with one anchor for the whole organization to manage it. I am trying to update organization entity with another user from "HAS_EMPLOYEE" list to become a new anchor. But there are no changes in db after the method and no runtime exceptions are thrown.
#Transactional
public OrganizationDTO changeAnchorForOrganization(UUID prevAnchorId, UUID newAnchorId) {
User newAnchor = userService.getAnyUserById(newAnchorId);
if (!newAnchor.isActive()) {
throw new BadRequestException(ExceptionType.REQUEST_BODY_INVALID);
}
User prevAnchor = userService.getAnyUserById(prevAnchorId);
Organization organization = getOrganizationByAnchorId(prevAnchorId);
Set<String> prevAnchorPermissions = prevAnchor.getPermissions();
prevAnchorPermissions.remove(SubRolesConstants.anchor);
prevAnchor.setPermissions(prevAnchorPermissions);
Set<String> newAnchorPermissions = newAnchor.getPermissions();
newAnchorPermissions.add(SubRolesConstants.anchor);
newAnchor.setPermissions(newAnchorPermissions);
organization.setAnchor(newAnchor);
return organizationMapper.entityToDTO(organization);
}
organization.setAnchor(newAnchor); this line is not working?
The result DTO has the changes made to org anchor but db is not. And if i'll try to get the ogranization after this method i'll get the old version of organization(with previous anchor)
Stuck with that for a long time. Maybe somebody can help me?
I was missing organizationRepository.save(organization).I think it's because of neo4j because by default #Transactional annotation commit any changes made to entities at the end of the service call. Or it's just a bug.

How to update the content inside of Page object from Spring Data without changing the other properties

after querying from the database using the given getAll(Pageable pageable) method from spring data jpa i become an Page object. What I am doing is modifing the content list inside of this Page object but I am getting stuck here is that I dont know how to set it back to the Page object because Page doesn't have setter method, something like page.setContent(newContent), it has only getter.
Can anyone give me some hints how to set the new content to the Page object without changing the other current properties inside of it?
You need to use PageImpl(List content, Pageable pageable, long total) as example below :
//get paged data
Page<Groups> groups = groupsRepository.
findPagedGroups(pageable, lowerCase(name), lowerCase(description));
// update list
List<Groups> groupsList = groups.stream().collect(Collectors.toList());
for (Groups group : groupsList) {
group.setSize(usersGroupsRepository.countActiveUsersGroupsForGroupId(group.getId()));
}
// return new PageImpl
return new PageImpl<>(groupsList, pageable, groups.getTotalElements());

Spring REST ResponseEntity how to return response when we have two objects

1. For example UserProfile which has 3 properties name,dob, age
2. And 2nd class let's say UserProfileResponse which has only "id"
public ResponseEntity<UserProfileResponse> createUserProfile(#RequestBody UserProfile userProfile)
{
UserProfileResponse userProfileResponse = new UserProfileResponse();
userProfileResponse.setId(??) // How do I set ID?
**createUserProfileData(userProfile) /// This is used to create DB record**
return new ResponseEntity<UserProfileResponse>(userProfileResponse,HTTPStatus.OK);
}
So for this userProfileResponse.setId(??) how can I set the ID value?
can I directly do like this userProfileResponse.setId(userProfileResponse.getId());
Or I can Pass one more request body like this
ResponseEntity<UserProfileResponse> createUserProfile(#RequestBody UserProfile userProfile, #RequestBody ID)
Thanks in advance.
You can call createUserProfileData method and return the id of the newly inserted object from it.
In createUserProfileData method, you can call saveAndFlush method of the repository which will save the userProfile Object.
This will return the id of the newly inserted object.
Finally your code will look like below:
public ResponseEntity<UserProfileResponse> createUserProfile(#RequestBody UserProfile userProfile)
{
UserProfileResponse userProfileResponse = new UserProfileResponse();
int id = createUserProfileData(userProfile)
userProfileResponse.setId(id)
return new ResponseEntity<UserProfileResponse>(userProfileResponse,HTTPStatus.OK);
}
If you want to get a value from the RequestBody UserProfile which it didn't contain it actually.Sorry it's impossible.
And we only could receive one requestBody at one time,so we need to use some other ways to collect the info.There is some other solutions:
Use #PathVariable to get ID from url
Use #RequestParam to get Id from requestParam
Add a new field named Id into your UserProfile
Use other way that that could get your Id,this depend how you persistent or generate the Id.
In your case,I'm not sure what you are going to do with the id.
If the "createUserProfileData" method means you need to offer an id first for persistence.
Well,I dont know which database and what kind of framework you are using.As I know,most of framework and database has the ability to generate the id automatically.But if you insist to generate id by your self,I recommend you UUID.
If the "createUserProfileData" method is saving the UserProfile to the database literally and the id is generated by the database itself,then you just do it and put the Id represent the record you just saved to UserProfileResponse.
As to how to get the id represent the record you just saved?It's up to the framework you're using and precisely how the code is written.

spring model is sometimes empty

i am confused about availibility from data within spring-model.
Example:
#RequestMapping("myAbosolutPathAAA.action")
public String myHandlerONE(#RequestParam(required = false) String date, Model model){
ArryList<Car> myCars = carsDAO.findAll(); //retrieve all cars from DB.
model.addAttribute(CARS, myCars);
return "page1.action";
}
Now i can handle my car-list on frontend.
At next i navigate on next controler-handler, where i need myCars-list again.
So i dont want to retrieve database anymore. I want to retrieve my spring-model:
#RequestMapping("myAbosolutPathBBB.action")
public String myHandlerTWO(#RequestParam String name, Model model){
ArryList<Car> myCars = model.asMap().get(CARS); //retrieve spring-model and not db .
//do somethings with car list....
return "page2.action";
}
But when i want to retrieve spring-model, my car-list is null.
Sometimes it works. I can not finde any explanation on spring-reference.
Can's anybody explain, when can i retrieve spring-model and when not?

JPA MERGE failed to update entity field value when this field is a collection(using ElementCollection)

Here we have a Manifest class that includes list of students and teachers, both could be null.
class Manifest{
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(name = "MANIFEST_STUDENT")
List<String> students = new ArrayList<String>();
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(name = "MANIFEST_TEACHER")
List<String> teachers = new ArrayList<String>();;
#ElementCollection(fetch = FetchType.EAGER)
#CollectionTable(name = "MANIFEST_OTHERS")
List<String> others = new ArrayList<String>();;
}
on the UI, there are two multiple select, one for student and one for teacher that let user choose for current manifest.
here is the problem:
When user deselect all students or teachers from the list(meaning remove all students or teachers from current manifest) and click save, unfortunately nothing can be saved, from UI and database it shows that the multiselect chosen looks the SAME as before.
from service layer, the code is simply like this.
manifest.merge();
It seems we must keep at least one student or teacher for the collection field to make the change valid. So what's going on here and what is the solution? BTW, we are on Openjpa.
Kind of resolve the issue, more like a work around:
Before calling merge(), place several condition checkers to make sure the collection fields are not null
public void save(Manifest entity) {
if(entity.getStudents()==null){
entity.setStudents(new ArrayList<String>());
}
if(entity.getTeachers()==null){
entity.setTeachers(new ArrayList<String>());
}
if(entity.getOthers()==null){
entity.setOthers(new ArrayList<String>());
}
entity.merge();
}
Simple as it, it seems the UI returns those collection fields as null even we initiate them as with empty String lists.
cheers.
Initializing a value in a JPA managed class, such as class Manifest, has no bearing on what, or how, JPA will create the class as JPA maps extracted rows to the class. In particular, the result of:
List<String> students = new ArrayList<String>();
is likely to be:
On creation (by JPA) of a new instance, assign an ArrayList<String>() to students.
JPA overwrites students with the data it extracts - the empty ArrayList is dereferenced/lost.
If your code is clearing a list, such as students, use obj.getStudents().clear(). More likely to run into problems if you call obj.setStudents(someEmptyList).
The issue here is how the JPA manager handles empty datasets: as null or as an empty list. The JPA spec (old, not sure about the just released update) doesn't take a position on this point. A relevant article here.
From your comments, it's apparent that OpenJPA may not be respecting a null value for a Collection/List, while it happily manages the necessary changes for when the value is set to an empty list instead. Someone knowing more about OpenJPA than I may be able to help at this stage - meanwhile you've got a workaround.

Resources