JPA Repository save method creates new instance instead of merging - jpa

In my project there are events that users sign up for. When a user signs up for an event, the events capacity decreases by 1 and the users name is added to a String attribute for the event. After these changes are made to the event in my code, I call eventsRepository.save(event), which I thought just merges the newly updated event, but for some reason my database is just creating a whole new event with a new ID with the new values.
Here are some pictures of the issue:
The event data before a user signs up (UUID in repository included)
The event data after a user signs up
Code for a User:
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import ymca.tracker.application.data.AbstractEntity;
#Embeddable
#Entity
public class User extends AbstractEntity {
private boolean familyAccount;
private String firstName;
private String lastName;
private String username;
private String password;
private String passwordSalt;
private String passwordHash;
private ymca.tracker.application.data.entity.Role role;
public User() {
}
public User(boolean familyAccount, String firstName, String lastName,
String username, String password, ymca.tracker.application.data.entity.Role role) {
this.familyAccount = familyAccount;
this.firstName = firstName;
this.lastName = lastName;
this.username = username;
this.role = role;
this.password = password;
this.passwordSalt = RandomStringUtils.random(32);
this.passwordHash = DigestUtils.sha1Hex(password + passwordSalt);
}
public boolean checkPassword(String password) {
return DigestUtils.sha1Hex(password + passwordSalt).equals(passwordHash);
}
public boolean getFamilyAccount() {
return familyAccount;
}
public void setFamilyAccount(boolean familyAccount) {
this.familyAccount = familyAccount;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordSalt() {
return passwordSalt;
}
public void setPasswordSalt(String passwordSalt) {
this.passwordSalt = passwordSalt;
}
public String getPasswordHash() {
return passwordHash;
}
public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash;
}
public ymca.tracker.application.data.entity.Role getRole() {
return role;
}
public void setRole(ymca.tracker.application.data.entity.Role role) {
this.role = role;
}
}
Code for an Events:
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import ymca.tracker.application.data.AbstractEntity;
#Embeddable
#Entity
public class Events extends AbstractEntity {
private String name;
private java.time.LocalDate startDate;
private java.time.LocalDate endDate;
private java.time.LocalTime startTime;
private java.time.LocalTime endTime;
private String recurring;
private int participants;
private String nonMemberPrice;
private String memberPrice;
private String location;
private String description;
private String users;
// Not currently used
#ElementCollection
#OneToMany(fetch = FetchType.LAZY)
private List<User> registrants = new ArrayList<User>();
public Events() {
}
public Events(String name, LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime,
String recurring, int participants, String nonMemberPrice, String memberPrice, String location,
String description, String users, List<User> registrants) {
this.name = name;
this.startDate = startDate;
this.endDate = endDate;
this.startTime = startTime;
this.endTime = endTime;
this.recurring = recurring;
this.participants = participants;
this.nonMemberPrice = nonMemberPrice;
this.memberPrice = memberPrice;
this.location = location;
this.description = description;
this.users = " ";
this.registrants = registrants;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public java.time.LocalDate getStartDate() {
return startDate;
}
public void setStartDate(java.time.LocalDate startDate) {
this.startDate = startDate;
}
public java.time.LocalDate getEndDate() {
return endDate;
}
public void setEndDate(java.time.LocalDate endDate) {
this.endDate = endDate;
}
public java.time.LocalTime getStartTime() {
return startTime;
}
public void setStartTime(java.time.LocalTime startTime) {
this.startTime = startTime;
}
public java.time.LocalTime getEndTime() {
return endTime;
}
public void setEndTime(java.time.LocalTime endTime) {
this.endTime = endTime;
}
public String getRecurring() {
return recurring;
}
public void setRecurring(String recurring) {
this.recurring = recurring;
}
public int getParticipants() {
return participants;
}
public void setParticipants(int participants) {
this.participants = participants;
}
public void decreaseCapacity(int numToDecreaseBy) {
this.participants = this.participants - numToDecreaseBy;
}
public String getMemberPrice() {
return memberPrice;
}
public void setMemberPrice(String memberPrice) {
this.memberPrice = memberPrice;
}
public String getNonMemberPrice() {
return nonMemberPrice;
}
public void setNonMemberPrice(String nonMemberPrice) {
this.nonMemberPrice = nonMemberPrice;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public String getUsers() {
return users;
}
public void setUsers(String users) {
this.users = users;
}
public void addUser(String user) {
this.users = this.users + user + "\n";
}
public List<User> getRegistrants() {
return registrants;
}
public void setGuests(ArrayList<User> registrants) {
this.registrants = registrants;
}
public void addRegistrant(User user) {
this.registrants.add(user);
}
public void removeRegistrant(User user) {
this.registrants.remove(user);
}
public boolean checkRegistrant(User user) {
return this.registrants.contains(user);
}
}
Code for Guest Users to sign up located in this View (save call is marked with comment) (updated with id column code):
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.dialog.Dialog;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.Grid.SelectionMode;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.grid.dataview.GridListDataView;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.html.H2;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.notification.Notification.Position;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.orderedlayout.VerticalLayout;
import com.vaadin.flow.component.orderedlayout.FlexComponent.Alignment;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.UUID;
import ymca.tracker.application.data.entity.Events;
import ymca.tracker.application.data.entity.Role;
import ymca.tracker.application.data.entity.User;
import ymca.tracker.application.data.service.EventsRepository;
import ymca.tracker.application.data.service.EventsService;
import ymca.tracker.application.data.service.UserRepository;
import ymca.tracker.application.views.MainLayout;
#PageTitle("Guest Events")
#Route(value = "guest-events", layout = MainLayout.class)
public class GuestEventsView extends Div {
private EventsService eventsService;
private EventsRepository eventsRepository;
private UserRepository userRepository;
private Grid<Events> grid;
private GridListDataView<Events> gridListDataView;
private Grid.Column<Events> idColumn;
private Grid.Column<Events> signUpColumn;
private Grid.Column<Events> nameColumn;
private Grid.Column<Events> startDateColumn;
private Grid.Column<Events> endDateColumn;
private Grid.Column<Events> startTimeColumn;
private Grid.Column<Events> endTimeColumn;
private Grid.Column<Events> recurringColumn;
private Grid.Column<Events> participantsColumn;
private Grid.Column<Events> priceColumn;
private Grid.Column<Events> locationColumn;
private Grid.Column<Events> descriptionColumn;
public GuestEventsView(EventsService eventsService, EventsRepository eventsRepository, UserRepository userRepository) {
this.eventsService = eventsService;
this.eventsRepository = eventsRepository;
this.userRepository = userRepository;
addClassName("guest-events-view");
setSizeFull();
Button signUpButton = createSignUpButton();
add(signUpButton);
createGrid();
add(grid);
}
private void createGrid() {
createGridComponent();
addColumnsToGrid();
}
private void createGridComponent() {
grid = new Grid<>();
grid.setSelectionMode(SelectionMode.SINGLE);
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER, GridVariant.LUMO_COLUMN_BORDERS);
grid.setHeight("100%");
List<Events> events = getEvents();
gridListDataView = grid.setItems(events);
}
private void addColumnsToGrid() {
createIdColumn();
createNameColumn();
createStartDateColumn();
createEndDateColumn();
createStartTimeColumn();
createEndTimeColumn();
createRecurringColumn();
createParticipantsColumn();
createPriceColumn();
createLocationColumn();
createDescriptionColumn();
}
private Button createSignUpButton() {
// Create the Dialog object which will be the signUpForm
Dialog signUpForm = new Dialog();
// Create the layout for the signUpForm, passing in the Dialog and selected Event
VerticalLayout signUpFormLayout = createSignUpFormLayout(signUpForm);
// Add the created layout to the signUpForm
signUpForm.add(signUpFormLayout);
// Only the signUpForm can be interacted with when it appears on the screen
signUpForm.setModal(true);
Button signUpButton = new Button("Sign Up");
signUpButton.addClickListener(e -> signUpForm.open());
return signUpButton;
}
private VerticalLayout createSignUpFormLayout(Dialog signUpForm) {
signUpForm.getElement().setAttribute("aria-label", "Registration Form");
TextField firstName = new TextField("First Name");
TextField lastName = new TextField("Last Name");
H2 headline = new H2("Registration Form");
headline.getStyle().set("margin-top", "0");
Button cancel = new Button("Cancel", e -> signUpForm.close());
Button submit = new Button("Submit", e -> {
if(fillChecker(firstName.getValue(), lastName.getValue()) == true) {
String fn = firstName.getValue();
String ln = lastName.getValue();
User guest = new User(false, fn, ln,
"null", "null", Role.GUEST);
Set<Events> selected = grid.getSelectedItems();
Events[] curEvent = selected.toArray(new Events[1]);
Events selectedEvent = curEvent[0];
if(selectedEvent == null) {
Notification.show("No Event Selected!", 5000, Position.TOP_CENTER);
} else {
userRepository.save(guest); // Saves guest sign-up info to user repository
selectedEvent.addUser(fn + " " + ln);
selectedEvent.decreaseCapacity(1); // Decrease events participants count by 1
// ISSUE HERE
// Currently saves new version of event instead of merging
UUID toDelete = selectedEvent.getId();
eventsRepository.save(selectedEvent);
eventsRepository.deleteById(toDelete);
signUpForm.close();
Notification.show("Registered 1 Guest", 5000, Position.TOP_CENTER);
}
} else {
Notification.show("Please complete the form to register", 5000, Position.TOP_CENTER);
}
});
submit.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
HorizontalLayout buttonLayout = new HorizontalLayout(cancel, submit);
buttonLayout.setAlignItems(Alignment.END);
buttonLayout.getStyle().set("margin-top", "var(--lumo-space-m");
VerticalLayout signUpFormLayout = new VerticalLayout(headline, firstName, lastName, buttonLayout);
signUpFormLayout.setPadding(false);
signUpFormLayout.setSpacing(false);
signUpFormLayout.setAlignItems(Alignment.STRETCH);
signUpFormLayout.getStyle().set("width", "18rem").set("max-width", "100%");
return signUpFormLayout;
}
private boolean fillChecker(String firstName, String lastName) {
if(firstName.equals("") || lastName.equals("")) {
return false;
}
return true;
}
private void createIdColumn() {
idColumn = grid.addColumn(Events::getId, "id").setHeader("ID").setAutoWidth(true);
}
private void createNameColumn() {
nameColumn = grid.addColumn(Events::getName, "name").setHeader("Name").setAutoWidth(true);
}
private void createStartDateColumn() {
startDateColumn = grid.addColumn(Events::getStartDate, "startDate").setHeader("Start Date").setAutoWidth(true);
}
private void createEndDateColumn() {
startDateColumn = grid.addColumn(Events::getEndDate, "endDate").setHeader("End Date").setAutoWidth(true);
}
private void createStartTimeColumn() {
startTimeColumn = grid.addColumn(Events::getStartTime, "startTime").setHeader("Start Time").setAutoWidth(true);
}
private void createEndTimeColumn() {
startDateColumn = grid.addColumn(Events::getEndTime, "endTime").setHeader("End Time").setAutoWidth(true);
}
private void createRecurringColumn() {
recurringColumn = grid.addColumn(Events::getRecurring, "recurring").setHeader("Recurring?").setAutoWidth(true);
}
private void createParticipantsColumn() {
participantsColumn = grid.addColumn(Events::getParticipants, "participants").setHeader("Capacity").setAutoWidth(true);
}
private void createPriceColumn() {
priceColumn = grid.addColumn(Events::getNonMemberPrice, "price").setHeader("Price").setAutoWidth(true);
}
private void createLocationColumn() {
locationColumn = grid.addColumn(Events::getLocation, "location").setHeader("Location").setAutoWidth(true);
}
private void createDescriptionColumn() {
descriptionColumn = grid.addColumn(Events::getDescription, "description").setHeader("Description").setAutoWidth(true);
}
private List<Events> getEvents() {
List<Events> list = eventsService.findAllEvents();
List<Events> toReturn = new ArrayList<Events>();
Events e;
int size = list.size();
for(int i = 0; i < size; i++) {
Events temp = list.get(i);
e = createEvents(temp.getName(), temp.getStartDate(), temp.getEndDate(), temp.getStartTime(), temp.getEndTime(),
temp.getRecurring(), temp.getParticipants(), temp.getNonMemberPrice(), temp.getLocation(), temp.getDescription());
toReturn.add(e);
}
return toReturn;
}
private Events createEvents(String name, java.time.LocalDate startDate, java.time.LocalDate endDate,
java.time.LocalTime startTime, java.time.LocalTime endTime, String recurring, int participants,
String price, String location, String description) {
Events e = new Events();
e.setName(name);
e.setStartDate(startDate);
e.setEndDate(endDate);
e.setStartTime(startTime);
e.setEndTime(endTime);
e.setRecurring(recurring);
e.setParticipants(participants);
e.setNonMemberPrice(price);
e.setLocation(location);
e.setDescription(description);
return e;
}
};
Here is my AbstractEntity class:
import java.util.UUID;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;
#MappedSuperclass
public abstract class AbstractEntity {
#Id
#GeneratedValue
private UUID id;
public UUID getId() {
return id;
}
public void setId(UUID id) {
this.id = id;
}
#Override
public int hashCode() {
if (id != null) {
return id.hashCode();
}
return super.hashCode();
}
#Override
public boolean equals(Object obj) {
if (!(obj instanceof AbstractEntity)) {
return false; // null or other class
}
AbstractEntity other = (AbstractEntity) obj;
if (id != null) {
return id.equals(other.id);
}
return super.equals(other);
}
}
Results of adding an Id Column to the sign up grid:

What does AbstractEntity contain? I'm guessing that your are missing the #Id annotation on your unique identifier for events, or that it is not mapped and goes missing before the entity is saved to the database. Without the id JPA has no way of knowing that this is an updated entity instead of a new one.
Debug the code and check that the entity contains the right ID at this line:
eventsRepository.save(selectedEvent)

Related

how to save subset data of one collection in another collection in SpringBoot Mongo DB

I have 1 collection namely profile now since it has lots of properties and since in future I will be needing more properties i decided to add new data in new collection namely profile_details .I will be keeping 1 field in profile_details namely profileId whose value will be same as primary key of collection profile.
I will be saving data of profile in profile collection using profileRepository.save(profile)
In order to save data in profile_details collection I am using aggregation pipeline in order to save data of profile_details collection but $out operator replaces documents instead of inserting new documents.Below is my sample code.Any help will be deeply appreciated
Profile.java
import java.io.Serializable;
import java.time.Instant;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.data.annotation.CreatedDate;
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.LastModifiedDate;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import org.springframework.stereotype.Component;
import com.fasterxml.jackson.annotation.JsonIgnoreProperties;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.juv.common.bean.model.RecentHealthMetricData;
import com.juv.common.enums.CurrentLanding;
import com.juv.common.enums.MFAPreference;
import com.juv.common.enums.Status;
import com.juv.common.primary.bean.model.Answer;
import com.juv.common.primary.bean.model.DeviceIntegrations;
import com.juv.common.primary.bean.model.DeviceToken;
#Document(collection = "profile")
#JsonIgnoreProperties(ignoreUnknown = true)
#Component
public class Profile extends ProfileDetails implements Serializable {
/**
*
*/
private static final long serialVersionUID = 6608898578832145751L;
#Id
private String profileId;
#Field("kibo_user_id")
#JsonProperty("kibo_user_id")
private String kiboUserId;
#Field("new_recommendations")
#JsonProperty("new_recommendations")
private List<String> newRecommendations;
#Field("kibo_id")
#JsonProperty("kibo_id")
private String kiboId;
#Field("original_kibo_id")
#JsonProperty("original_kibo_id")
private String originalKiboId;
#Field("email")
#JsonProperty("email")
private String email;
#Field("country")
#JsonProperty("country")
private String country;
#Field("first_name")
#JsonProperty("first_name")
private String firstName;
#Field("last_name")
#JsonProperty("last_name")
private String lastName;
#CreatedDate
#Field("created_date")
#JsonProperty("created_date")
private Date createdDate;
#Field("registration_date")
#JsonProperty("registration_date")
private Date registrationDate;
#LastModifiedDate
#Field("last_modified")
#JsonProperty("last_modified")
private Date lastModified;
#Field("phi_mapping_id")
#JsonProperty("phi_mapping_id")
private String phiMappingId;
#Field("phone_number")
#JsonProperty("phone_number")
private String phoneNumber;
#Field("origin")
#JsonProperty("origin")
private String origin;
#Field("gender")
#JsonProperty("gender")
private String gender;
#Field("status")
#JsonProperty("status")
private Status status;
#Field("current_landing")
#JsonProperty("current_landing")
private CurrentLanding currentLanding;
#Field("mfa_preference")
#JsonProperty("mfa_preference")
private MFAPreference mfaPreference;
#Field("profile_recommendation_info_id")
#JsonProperty("profile_recommendation_info_id")
private String profileRecommendationInfoId;
#Field("oldest_profile_recommendation_info_id")
#JsonProperty("oldest_profile_recommendation_info_id")
private String oldestProfileRecommendationInfoId;
#Field("last_question")
#JsonProperty("last_question")
private String lastQuestion;
#Field("answers")
#JsonProperty("answers")
private Answer[] answers;
#Field("is_account_locked")
#JsonProperty("is_account_locked")
private boolean isAccountLocked;
#Field("device_integrations")
#JsonProperty("device_integrations")
private DeviceIntegrations deviceIntegrations ;
#Field("profile_photo")
#JsonProperty("profile_photo")
private String profilePhoto;
#Field("device_token_list")
#JsonProperty("device_token_list")
private List<DeviceToken> deviceTokenList;
#Field("unit_map")
#JsonProperty("unit_map")
private Map<String,String> unitMap;
#Field("recent_health_metric_values")
#JsonProperty("recent_health_metric_values")
private Map<String,RecentHealthMetricData> recentHealthMetricValues;
#Field("last_recommendation_info_date")
#JsonProperty("last_recommendation_info_date")
private Date lastRecommendationInfoDate;
#Field("terms_conditions")
#JsonProperty("terms_conditions")
private boolean termsConditions;
#Field("health_metric_preferences")
#JsonProperty("health_metric_preferences")
private Map<String, String> healthMetricPreferences;
#Field("device_preferences")
#JsonProperty("device_preferences")
private Map<Integer, String> devicePreferences;
#Field("pinpoint_custom_atributes")
#JsonProperty("pinpoint_custom_atributes")
private Map<String,String> pinpointCustomAttributes;
#Field("opt_juvlab_customer")
#JsonProperty("opt_juvlab_customer")
private boolean optJuvLabsCustomer;
#Field("deleted")
#JsonProperty("deleted")
private boolean deleted;
#Field("deleted_timestamp")
#JsonProperty("deleted_timestamp")
private Instant deletedTimestamp;
#Field("daily_action_count_clevertap")
#JsonProperty("daily_action_count_clevertap")
private int dailyActionCountClevertap;
public String getProfileId() {
return profileId;
}
public void setProfileId(String profileId) {
this.profileId = profileId;
}
public String getKiboUserId() {
return kiboUserId;
}
public void setKiboUserId(String kiboUserId) {
this.kiboUserId = kiboUserId;
}
public String getKiboId() {
return kiboId;
}
public void setKiboId(String kiboId) {
this.kiboId = kiboId;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
if (email != null) {
email = email.toLowerCase();
}
this.email = email;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Date getCreatedDate() {
return createdDate;
}
public void setCreatedDate(Date createdDate) {
this.createdDate = createdDate;
}
public Date getRegistrationDate() {
return registrationDate;
}
public void setRegistrationDate(Date registrationDate) {
this.registrationDate = registrationDate;
}
public Date getLastModified() {
return lastModified;
}
public void setLastModified(Date lastModified) {
this.lastModified = lastModified;
}
public String getPhiMappingId() {
return phiMappingId;
}
public void setPhiMappingId(String phiMappingId) {
this.phiMappingId = phiMappingId;
}
public String getPhoneNumber() {
return phoneNumber;
}
public void setPhoneNumber(String phoneNumber) {
this.phoneNumber = phoneNumber;
}
public String getOrigin() {
return origin;
}
public void setOrigin(String origin) {
this.origin = origin;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
public Status getStatus() {
return status;
}
public void setStatus(Status status) {
this.status = status;
}
public CurrentLanding getCurrentLanding() {
return currentLanding;
}
public void setCurrentLanding(CurrentLanding currentLanding) {
this.currentLanding = currentLanding;
}
public MFAPreference getMfaPreference() {
return mfaPreference;
}
public void setMfaPreference(MFAPreference otpPreference) {
this.mfaPreference = otpPreference;
}
public String getProfileRecommendationInfoId() {
return profileRecommendationInfoId;
}
public void setProfileRecommendationInfoId(String profileRecommendationInfoId) {
this.profileRecommendationInfoId = profileRecommendationInfoId;
}
public String getLastQuestion() {
return lastQuestion;
}
public void setLastQuestion(String lastQuestion) {
this.lastQuestion = lastQuestion;
}
public Answer[] getAnswers() {
return answers;
}
public void setAnswers(Answer[] answers) {
this.answers = answers;
}
public boolean isAccountLocked() {
return isAccountLocked;
}
public void setAccountLocked(boolean isAccountLocked) {
this.isAccountLocked = isAccountLocked;
}
public enum ORIGIN {
APP,
KIBO,
SHOPIFY
}
public String getProfilePhoto() {
return profilePhoto;
}
public void setProfilePhoto(String profilePhoto) {
this.profilePhoto = profilePhoto;
}
public DeviceIntegrations getDeviceIntegrations() {
return deviceIntegrations;
}
public void setDeviceIntegrations(DeviceIntegrations deviceIntegrations) {
this.deviceIntegrations = deviceIntegrations;
}
public List<DeviceToken> getDeviceTokenList() {
return deviceTokenList;
}
public void setDeviceTokenList(List<DeviceToken> deviceTokenList) {
this.deviceTokenList = deviceTokenList;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public Map<String, String> getUnitMap() {
return unitMap;
}
public void setUnitMap(Map<String, String> unitMap) {
this.unitMap = unitMap;
}
public Date getLastRecommendationInfoDate() {
return lastRecommendationInfoDate;
}
public void setLastRecommendationInfoDate(Date lastRecommendationInfoDate) {
this.lastRecommendationInfoDate = lastRecommendationInfoDate;
}
public boolean isTermsConditions() {
return termsConditions;
}
public void setTermsConditions(boolean termsConditions) {
this.termsConditions = termsConditions;
}
public Map<String, String> getHealthMetricPreferences() {
return healthMetricPreferences;
}
public void setHealthMetricPreferences(Map<String, String> healthMetricPreferences) {
this.healthMetricPreferences = healthMetricPreferences;
}
public Map<String, String> getPinpointCustomAttributes() {
return pinpointCustomAttributes;
}
public void setPinpointCustomAttributes(Map<String, String> pinpointCustomAttributes) {
this.pinpointCustomAttributes = pinpointCustomAttributes;
}
public Map<Integer, String> getDevicePreferences() {
return devicePreferences;
}
public void setDevicePreferences(Map<Integer, String> devicePreferences) {
this.devicePreferences = devicePreferences;
}
public Map<String, RecentHealthMetricData> getRecentHealthMetricValues() {
if(recentHealthMetricValues==null) {
recentHealthMetricValues = new HashMap<>();
}
return recentHealthMetricValues;
}
public void setRecentHealthMetricValues(Map<String, RecentHealthMetricData> recentHealthMetricValues) {
this.recentHealthMetricValues = recentHealthMetricValues;
}
public List<String> getNewRecommendations() {
return newRecommendations;
}
public void setNewRecommendations(List<String> newRecommendations) {
this.newRecommendations = newRecommendations;
}
public boolean isOptJuvLabsCustomer() {
return optJuvLabsCustomer;
}
public void setOptJuvLabsCustomer(boolean optJuvLabsCustomer) {
this.optJuvLabsCustomer = optJuvLabsCustomer;
}
public boolean isDeleted() {
return deleted;
}
public void setDeleted(boolean deleted) {
this.deleted = deleted;
}
public Instant getDeletedTimestamp() {
return deletedTimestamp;
}
public void setDeletedTimestamp(Instant deletedTimestamp) {
this.deletedTimestamp = deletedTimestamp;
}
public String getOriginalKiboId() {
return originalKiboId;
}
public void setOriginalKiboId(String originalKiboId) {
this.originalKiboId = originalKiboId;
}
public String getOldestProfileRecommendationInfoId() {
return oldestProfileRecommendationInfoId;
}
public void setOldestProfileRecommendationInfoId(String oldestProfileRecommendationInfoId) {
this.oldestProfileRecommendationInfoId = oldestProfileRecommendationInfoId;
}
public int getDailyActionCountClevertap() {
return dailyActionCountClevertap;
}
public void setDailyActionCountClevertap(int dailyActionCountClevertap) {
this.dailyActionCountClevertap = dailyActionCountClevertap;
}
}
ProfileDetails.java
import org.springframework.data.mongodb.core.mapping.Document;
import org.springframework.data.mongodb.core.mapping.Field;
import com.fasterxml.jackson.annotation.JsonProperty;
#Document(collection = "profile_details")
public class ProfileDetails {
#Field("profile_id")
private String profileId;
#Field("partner_code")
#JsonProperty("partner_code")
private String partnerCode;
public String getProfileId() {
return profileId;
}
public void setProfileId(String profileId) {
this.profileId = profileId;
}
public String getPartnerCode() {
return partnerCode;
}
public void setPartnerCode(String partnerCode) {
this.partnerCode = partnerCode;
}
}
ProfileFragmentRepositoryImpl.java
package com.juv.common.secondary.repository.impl;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.aggregation.AddFieldsOperation;
import org.springframework.data.mongodb.core.aggregation.Aggregation;
import org.springframework.data.mongodb.core.aggregation.AggregationOptions;
import org.springframework.data.mongodb.core.aggregation.AggregationResults;
import org.springframework.data.mongodb.core.aggregation.ArrayOperators.ArrayElemAt;
import org.springframework.data.mongodb.core.aggregation.LimitOperation;
import org.springframework.data.mongodb.core.aggregation.LookupOperation;
import org.springframework.data.mongodb.core.aggregation.MatchOperation;
import org.springframework.data.mongodb.core.aggregation.OutOperation;
import org.springframework.data.mongodb.core.aggregation.SetOperation;
import org.springframework.data.mongodb.core.aggregation.SortOperation;
import org.springframework.data.mongodb.core.aggregation.UnsetOperation;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.stereotype.Component;
import com.juv.common.constants.CommonConstants;
import com.juv.common.secondary.dao.Profile;
import com.juv.common.secondary.dao.ProfileDetails;
import com.juv.common.secondary.repository.ProfileFragmentRepository;
import com.juv.common.secondary.repository.ProfileRepository;
import com.mongodb.internal.operation.InsertOperation;
#Component
public class ProfileFragmentRepositoryImpl implements ProfileFragmentRepository {
#Autowired
private MongoTemplate secondaryMongoTemplate;
#Autowired
private ProfileRepository profileRepository;
#Override
public void saveProfileDetails(Profile profile) {
MatchOperation filterOnProfileId = Aggregation.match(Criteria.where("profileId").is(profile.getProfileId()));
SetOperation setProfileId = SetOperation.set("profileId").toValue(profile.getProfileId());
SetOperation setPartnerCode = SetOperation.set("partnerCode").toValue(profile.getPartnerCode());
OutOperation outOperation = new OutOperation("profile_details").uniqueKey("profileId").insertDocuments();
Aggregation aggregation = Aggregation.newAggregation(filterOnProfileId,setProfileId,setPartnerCode,outOperation);
System.out.println("------------------------"+aggregation);
AggregationResults<ProfileDetails> output = secondaryMongoTemplate.aggregate(aggregation, Profile.class, ProfileDetails.class);
System.out.println("------------------------"+output);
}
}
$out operator replaces documents instead of inserting new documents.How can i make them insert data instead of replacing them

Grid not updating after entity attributes are changed

In my project, I have "Events" and "Users". Users sign up for events. Anyways the Events entity has a "participants" attribute which is an int that is the total capacity of the event, that is supposed to decrement every time a User signs up for the Event. Each Event also has an ArrayList attribute called "registrants" that is supposed to contain all the current User entities that have signed up for the Event.
My issue is that when a User signs up for an Event, this capacity attribute "participants" does not decrease at all like it is supposed to, which I suspect means the ArrayList "registrants" is also not be updated with the User that signs up. I re-check the EventManagementView after using a User to sign up for an event to see if the capacity is ever dropped from its initial set value, but it never is. Here's all the code that is directly used with this issue:
Events.java class for Events entity:
package ymca.tracker.application.data.entity;
import java.time.LocalDate;
import java.time.LocalTime;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.ElementCollection;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.OneToMany;
import ymca.tracker.application.data.AbstractEntity;
#Embeddable
#Entity
public class Events extends AbstractEntity{
private String name;
private java.time.LocalDate startDate;
private java.time.LocalDate endDate;
private java.time.LocalTime startTime;
private java.time.LocalTime endTime;
private String recurring;
// The capacity attribute I was referring to above
public int participants;
private String nonMemberPrice;
private String memberPrice;
private String location;
private String description;
// Registrants ArrayList that is supposed to hold all the User entities that sign up for an event
#ElementCollection
#OneToMany(fetch = FetchType.EAGER)
public List<User> registrants = new ArrayList<User>();
public Events() {
}
public Events(String name, LocalDate startDate, LocalDate endDate, LocalTime startTime, LocalTime endTime,
String recurring, int participants, String nonMemberPrice, String memberPrice, String location,
String description, ArrayList<User> registrants) {
this.name = name;
this.startDate = startDate;
this.endDate = endDate;
this.startTime = startTime;
this.endTime = endTime;
this.recurring = recurring;
this.participants = participants;
this.nonMemberPrice = nonMemberPrice;
this.memberPrice = memberPrice;
this.location = location;
this.description = description;
this.registrants = registrants;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public java.time.LocalDate getStartDate() {
return startDate;
}
public void setStartDate(java.time.LocalDate startDate) {
this.startDate = startDate;
}
public java.time.LocalDate getEndDate() {
return endDate;
}
public void setEndDate(java.time.LocalDate endDate) {
this.endDate = endDate;
}
public java.time.LocalTime getStartTime() {
return startTime;
}
public void setStartTime(java.time.LocalTime startTime) {
this.startTime = startTime;
}
public java.time.LocalTime getEndTime() {
return endTime;
}
public void setEndTime(java.time.LocalTime endTime) {
this.endTime = endTime;
}
public String getRecurring() {
return recurring;
}
public void setRecurring(String recurring) {
this.recurring = recurring;
}
public int getParticipants() {
return participants;
}
public void setParticipants(int participants) {
this.participants = participants;
}
// This method is called (only with value 1 for now) to decrease participants count
public void decreaseCapacity(int numToDecreaseBy) {
this.participants = this.participants - numToDecreaseBy;
}
public String getMemberPrice() {
return memberPrice;
}
public void setMemberPrice(String memberPrice) {
this.memberPrice = memberPrice;
}
public String getNonMemberPrice() {
return nonMemberPrice;
}
public void setNonMemberPrice(String nonMemberPrice) {
this.nonMemberPrice = nonMemberPrice;
}
public String getLocation() {
return location;
}
public void setLocation(String location) {
this.location = location;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
public List<User> getRegistrants() {
return registrants;
}
public void setGuests(ArrayList<User> registrants) {
this.registrants = registrants;
}
// This method is called to add a User to the registrants ArrayList
public void addRegistrant(User user) {
this.registrants.add(user);
}
public void removeRegistrant(User user) {
this.registrants.remove(user);
}
}
User.java class for User entity:
package ymca.tracker.application.data.entity;
import javax.persistence.Embeddable;
import javax.persistence.Entity;
import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.RandomStringUtils;
import ymca.tracker.application.data.AbstractEntity;
#Embeddable
#Entity
public class User extends AbstractEntity {
private boolean familyAccount;
private String firstName;
private String lastName;
private String username;
private String password;
private String passwordSalt;
private String passwordHash;
private ymca.tracker.application.data.entity.Role role;
public User() {
}
public User(boolean familyAccount, String firstName, String lastName,
String username, String password, ymca.tracker.application.data.entity.Role role) {
this.familyAccount = familyAccount;
this.firstName = firstName;
this.lastName = lastName;
this.username = username;
this.role = role;
this.password = password;
this.passwordSalt = RandomStringUtils.random(32);
this.passwordHash = DigestUtils.sha1Hex(password + passwordSalt);
}
public boolean checkPassword(String password) {
return DigestUtils.sha1Hex(password + passwordSalt).equals(passwordHash);
}
public boolean getFamilyAccount() {
return familyAccount;
}
public void setFamilyAccount(boolean familyAccount) {
this.familyAccount = familyAccount;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordSalt() {
return passwordSalt;
}
public void setPasswordSalt(String passwordSalt) {
this.passwordSalt = passwordSalt;
}
public String getPasswordHash() {
return passwordHash;
}
public void setPasswordHash(String passwordHash) {
this.passwordHash = passwordHash;
}
public ymca.tracker.application.data.entity.Role getRole() {
return role;
}
public void setRole(ymca.tracker.application.data.entity.Role role) {
this.role = role;
}
}
My Staff/Admin account uses this EventManagementView below to initially create the event:
package ymca.tracker.application.views.eventmanagement;
import com.vaadin.flow.component.Component;
import com.vaadin.flow.component.HasStyle;
import com.vaadin.flow.component.UI;
import com.vaadin.flow.component.button.Button;
import com.vaadin.flow.component.button.ButtonVariant;
import com.vaadin.flow.component.datepicker.DatePicker;
import com.vaadin.flow.component.dependency.Uses;
import com.vaadin.flow.component.formlayout.FormLayout;
import com.vaadin.flow.component.grid.Grid;
import com.vaadin.flow.component.grid.GridVariant;
import com.vaadin.flow.component.html.Div;
import com.vaadin.flow.component.icon.Icon;
import com.vaadin.flow.component.notification.Notification;
import com.vaadin.flow.component.orderedlayout.HorizontalLayout;
import com.vaadin.flow.component.splitlayout.SplitLayout;
import com.vaadin.flow.component.textfield.IntegerField;
import com.vaadin.flow.component.textfield.TextField;
import com.vaadin.flow.component.timepicker.TimePicker;
import com.vaadin.flow.data.binder.BeanValidationBinder;
import com.vaadin.flow.data.binder.ValidationException;
import com.vaadin.flow.router.BeforeEnterEvent;
import com.vaadin.flow.router.BeforeEnterObserver;
import com.vaadin.flow.router.PageTitle;
import com.vaadin.flow.router.Route;
import com.vaadin.flow.spring.data.VaadinSpringDataHelpers;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.UUID;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import ymca.tracker.application.data.entity.Events;
import ymca.tracker.application.data.entity.User;
import ymca.tracker.application.data.service.EventsService;
#PageTitle("Event Management")
#Route(value = "event-management")
#Uses(Icon.class)
public class EventManagementView extends Div implements BeforeEnterObserver {
private final String EVENTS_ID = "eventsID";
private final String EVENTS_EDIT_ROUTE_TEMPLATE = "event-management/%s/edit";
private Grid<Events> grid = new Grid<>(Events.class, false);
private TextField name;
private DatePicker startDate;
private DatePicker endDate;
private TimePicker startTime;
private TimePicker endTime;
private TextField recurring;
private IntegerField participants;
private TextField nonMemberPrice;
private TextField memberPrice;
private TextField location;
private TextField description;
private Button delete = new Button("Delete");
private Button cancel = new Button("Cancel");
private Button save = new Button("Save");
private BeanValidationBinder<Events> binder;
private Events events;
private EventsService eventsService;
public EventManagementView(#Autowired EventsService eventsService) {
this.eventsService = eventsService;
addClassNames("event-management-view", "flex", "flex-col", "h-full");
// Create UI
SplitLayout splitLayout = new SplitLayout();
splitLayout.setSizeFull();
createGridLayout(splitLayout);
createEditorLayout(splitLayout);
add(splitLayout);
// Configure Grid
grid.addColumn("name").setAutoWidth(true);
grid.addColumn("startDate").setAutoWidth(true);
grid.addColumn("endDate").setAutoWidth(true);
grid.addColumn("startTime").setAutoWidth(true);
grid.addColumn("endTime").setAutoWidth(true);
grid.addColumn("recurring").setAutoWidth(true);
grid.addColumn("participants").setAutoWidth(true);
grid.addColumn("nonMemberPrice").setAutoWidth(true);
grid.addColumn("memberPrice").setAutoWidth(true);
grid.addColumn("location").setAutoWidth(true);
grid.addColumn("description").setAutoWidth(true);
grid.setItems(query -> eventsService.list(
PageRequest.of(query.getPage(), query.getPageSize(), VaadinSpringDataHelpers.toSpringDataSort(query)))
.stream());
grid.addThemeVariants(GridVariant.LUMO_NO_BORDER);
grid.setHeightFull();
// when a row is selected or deselected, populate form
grid.asSingleSelect().addValueChangeListener(event -> {
if (event.getValue() != null) {
UI.getCurrent().navigate(String.format(EVENTS_EDIT_ROUTE_TEMPLATE, event.getValue().getId()));
} else {
clearForm();
UI.getCurrent().navigate(EventManagementView.class);
}
});
// Configure Form
binder = new BeanValidationBinder<>(Events.class);
// Bind fields. This is where you'd define e.g. validation rules
binder.bindInstanceFields(this);
delete.addClickListener(e -> {
binder.removeBean();
eventsService.delete(this.events.getId());
eventsService.update(this.events);
clearForm();
refreshGrid();
Notification.show("Event deleted");
UI.getCurrent().navigate(EventManagementView.class);
});
cancel.addClickListener(e -> {
clearForm();
refreshGrid();
});
save.addClickListener(e -> {
try {
if (this.events == null) {
this.events = new Events();
}
/*
Since the ArrayList isn't set by the grid editor, I hardcoded an
empty ArrayList to go with the new Event here
*/
ArrayList<User> registrants = new ArrayList<User>();
this.events.setGuests(registrants);
binder.writeBean(this.events);
eventsService.update(this.events);
clearForm();
refreshGrid();
Notification.show("Event details saved.");
UI.getCurrent().navigate(EventManagementView.class);
} catch (ValidationException validationException) {
Notification.show("An exception happened while trying to save the event details.");
}
});
}
#Override
public void beforeEnter(BeforeEnterEvent event) {
Optional<UUID> eventsId = event.getRouteParameters().get(EVENTS_ID).map(UUID::fromString);
if (eventsId.isPresent()) {
Optional<Events> eventsFromBackend = eventsService.get(eventsId.get());
if (eventsFromBackend.isPresent()) {
populateForm(eventsFromBackend.get());
} else {
Notification.show(
String.format("The requested event was not found, ID = %s", eventsId.get()), 3000,
Notification.Position.BOTTOM_START);
// when a row is selected but the data is no longer available,
// refresh grid
refreshGrid();
event.forwardTo(EventManagementView.class);
}
}
}
private void createEditorLayout(SplitLayout splitLayout) {
Div editorLayoutDiv = new Div();
editorLayoutDiv.setClassName("flex flex-col");
editorLayoutDiv.setWidth("400px");
Div editorDiv = new Div();
editorDiv.setClassName("p-l flex-grow");
editorLayoutDiv.add(editorDiv);
FormLayout formLayout = new FormLayout();
name = new TextField("Event Name");
startDate = new DatePicker("Start Date");
endDate = new DatePicker("End Date");
startTime = new TimePicker("Start Time");
startTime.setStep(Duration.ofMinutes(10));
endTime = new TimePicker("End Time");
endTime.setStep(Duration.ofMinutes(10));
recurring = new TextField("Recurring Event?");
participants = new IntegerField("Number of Participants");
nonMemberPrice = new TextField("Non-Member Price");
memberPrice = new TextField("Member Price");
location = new TextField("Location");
description = new TextField("Description");
Component[] fields = new Component[]{name, startDate, endDate, startTime, endTime, recurring, participants, nonMemberPrice, memberPrice, location, description};
for (Component field : fields) {
((HasStyle) field).addClassName("full-width");
}
formLayout.add(fields);
editorDiv.add(formLayout);
createButtonLayout(editorLayoutDiv);
splitLayout.addToSecondary(editorLayoutDiv);
}
private void createButtonLayout(Div editorLayoutDiv) {
HorizontalLayout buttonLayout = new HorizontalLayout();
buttonLayout.setClassName("w-full flex-wrap bg-contrast-5 py-s px-l");
buttonLayout.setSpacing(true);
cancel.addThemeVariants(ButtonVariant.LUMO_TERTIARY);
save.addThemeVariants(ButtonVariant.LUMO_PRIMARY);
delete.addThemeVariants(ButtonVariant.LUMO_ERROR);
buttonLayout.add(save, cancel, delete);
editorLayoutDiv.add(buttonLayout);
}
private void createGridLayout(SplitLayout splitLayout) {
Div wrapper = new Div();
wrapper.setId("grid-wrapper");
wrapper.setWidthFull();
splitLayout.addToPrimary(wrapper);
wrapper.add(grid);
}
private void refreshGrid() {
grid.select(null);
grid.getLazyDataView().refreshAll();
}
private void clearForm() {
populateForm(null);
}
private void populateForm(Events value) {
this.events = value;
binder.readBean(this.events);
}
}
The portion of code that handles event sign up for a User (If you'd prefer to see the whole class for this view instead of just this method please let me know):
private VerticalLayout createSignUpFormLayout(Dialog signUpForm) {
signUpForm.getElement().setAttribute("aria-label", "Registration Form");
TextField firstName = new TextField("First Name");
TextField lastName = new TextField("Last Name");
H2 headline = new H2("Registration Form");
headline.getStyle().set("margin-top", "0");
Button cancel = new Button("Cancel", e -> signUpForm.close());
Button submit = new Button("Submit", e -> {
if(fillChecker(firstName.getValue(), lastName.getValue()) == true) {
String fn = firstName.getValue();
String ln = lastName.getValue();
User guest = new User(false, fn, ln,
"null", "null", Role.GUEST);
Set<Events> selected = grid.getSelectedItems();
Events[] curEvent = selected.toArray(new Events[1]);
Events selectedEvent = curEvent[0];
if(selectedEvent == null) {
Notification.show("No Event Selected!", 5000, Position.TOP_CENTER);
} else {
userRepository.save(guest); // Saves guest sign-up info to user repository
selectedEvent.addRegistrant(guest);; // Adds guest sign-up info to events guest list
selectedEvent.decreaseCapacity(1); // Decrease events participants count by 1
signUpForm.close();
Notification.show("Registered 1 Guest", 5000, Position.TOP_CENTER);
}
} else {
Notification.show("Please complete the form to register", 5000, Position.TOP_CENTER);
}
});

JPA: How to map one entity's property value to collection property of another entity

I have two entities, naming Sport and Image.
As the title above, how can I map the value of property, sportId at Sport to the #ManyToOne collection property at Image? For instance, I want the value of sportId (eg. 1) to be displayed at collection property field of sportId at Image. How can I achieve this?
Sport.java
#Views({#View(members= "title; date; estimatedCost; attendance; remark; images"),
#View(name="NoImagesCollection", members= "sportId; title; date; estimatedCost; attendance; remark")})
#Entity
public class Sport {
//******************************FORM ID******************************//
#Id
#Hidden
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="SPORT_ID", length=10, unique = true, nullable = false, updatable = false)
private int sportId;
#NoCreate
#NoModify
#OneToMany(fetch = FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="sports")
private Collection<Image> images;
//******************************TITLE******************************//
#Column(name="SPORT_TITLE", precision=2000)
#Required
private String title;
//******************************DATE START******************************//
// #Stereotype("DATE")
#Column(name="SPORT_DATE")
#Required
private Date date;
//******************************ESTIMATED COST******************************//
#Hidden
#Stereotype("MONEY")
#Column(name="SPORT_EST_COST")
#Required
private BigDecimal estimatedCost; // Include the import java.math.* BigDecimal is typically used for money
//******************************ESTIMATED ATTENDEES******************************//
#Hidden
#Column(name="SPORT_ATTENDANCE", length=10)
#Required
private int attendance;
//******************************REMARK******************************//
#Hidden
#Editor("TextAreaNoFrame")
#Stereotype("MEMO")
#Column(name="SPORT_REMARK", precision=2000)
private String remark;
//******************************ENTERED DATE******************************//
#Hidden
#Column(name="ENTERED_DATE")
#Temporal(TemporalType.TIMESTAMP)
private Date enteredDate;
#PrePersist
private void setCreateDate() {
enteredDate = new Date();
}
//******************************MODIFIED DATE******************************//
#Hidden
#Column(name="MODIFIED_DATE")
#Temporal(TemporalType.TIMESTAMP)
private Date modifiedDate;
#PostUpdate
private void updateModifyDate() {
modifiedDate = new Date();
}
//******************************GETTERS AND SETTERS FOR ALL PROPERTIES******************************//
public int getSportId() {
return sportId;
}
public void setSportId(int sportId) {
this.sportId = sportId;
}
public String getTitle() {
return title;
}
public void setTitle(String title) {
this.title = title;
}
public Date getDate() {
return date;
}
public void setDate(Date date) {
this.date = date;
}
public BigDecimal getEstimatedCost() {
return estimatedCost;
}
public void setEstimatedCost(BigDecimal estimatedCost) {
this.estimatedCost = estimatedCost;
}
public int getAttendance() {
return attendance;
}
public void setAttendance(int attendance) {
this.attendance = attendance;
}
public String getRemark() {
return remark;
}
public void setRemark(String remark) {
this.remark = remark;
}
public Date getEnteredDate() {
return enteredDate;
}
public void setEnteredDate(Date enteredDate) {
this.enteredDate = enteredDate;
}
public Date getModifiedDate() {
return modifiedDate;
}
public void setModifiedDate(Date modifiedDate) {
this.modifiedDate = modifiedDate;
}
public Collection<Image> getImages() {
return images;
}
public void setImages(Collection<Image> images) {
this.images = images;
}
}
Image.java
#View(members="sports; image")
#Entity
public class Image {
#Id
#Hidden
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="IMG_ID", unique = true, nullable = false, updatable = false)
private int imgId;
#Required
#Column(name="IMG_IMAGE")
#Stereotype("PHOTO")
private byte [] image;
#ReferenceView("NoImagesCollection")
#Required
#NoFrame
#ManyToOne(optional=true)
#JoinColumn(name="IMG_SPORT_ID", nullable = false)
private Sport sports;
#Hidden
#Column(name="ENTERED_DATE")
#Temporal(TemporalType.TIMESTAMP)
private Date penteredDate;
#PrePersist
private void setCreateDate() {
penteredDate = new Date();
}
#Hidden
#Column(name="MODIFIED_DATE")
#Temporal(TemporalType.TIMESTAMP)
private Date pmodifiedDate;
#PostUpdate
private void updateModifyDate() {
pmodifiedDate = new Date();
}
public int getImgId() {
return imgId;
}
public void setImgId(int imgId) {
this.imgId = imgId;
}
public byte[] getImage() {
return image;
}
public void setImage(byte[] image) {
this.image = image;
}
public Sport getSports() {
return sports;
}
public void setSports(Sport sports) {
this.sports = sports;
}
public Date getPenteredDate() {
return penteredDate;
}
public void setPenteredDate(Date penteredDate) {
this.penteredDate = penteredDate;
}
public Date getPmodifiedDate() {
return pmodifiedDate;
}
public void setPmodifiedDate(Date pmodifiedDate) {
this.pmodifiedDate = pmodifiedDate;
}
}
ListSportImagesAction.java
public class ListSportImagesAction extends TabBaseAction implements IForwardAction {
private int row;
#Inject
private Tab tab;
public void execute() throws Exception {
Map sportKey = (Map) tab.getTableModel().getObjectAt(row);
int sportId = ((Integer) sportKey.get("sportId")).intValue();
Tab imageTab = (Tab)getContext().get("CkSurvey", getForwardURI(), "xava_tab");
imageTab.setBaseCondition("${sport.sportId} = " + sportId);
System.out.println("id================="+sportId);
}
public int getRow() {
return row;
}
public void setRow(int row) {
this.row = row;
}
public Tab getTab() {
return tab;
}
public void setTab(Tab tab) {
this.tab = tab;
}
#Override
public String getForwardURI() {
return "/m/Image";
}
#Override
public boolean inNewWindow() {
return true;
}
}
Any guidance provided will be appreciated.
--Edited--
I have added the code for the action that map the value. I fail to display the value at the property field, although it is displayed at Eclipse's console.

Rest Client: Javax.ws.rs

i'm starting with Rest and don't have no idea how to implement it properly. I got an exercise: i must implement a Rest-Client with the RestClient-API from javax.ws.rs standard library and i tried by using the code below, but i'm getting a null pointer exception. But the resource are there and when i try directly from the browser (http://localhost:8080/sep/rest/customers/112). Now my question how can i do it properly. Some constraints, i must use XML (not JSON) for the Data-support.
Hier my client-code:
public Response createCustomer(Customer customer){
log.info("Starting: Rest Create a Customer with Name: " + Customer.class.getName());
this.customerWebTarget = this.client.target(URL);
Response response = this.customerWebTarget.request().
buildPost(Entity.entity(customer, MediaType.APPLICATION_XML)).invoke();
log.info("Ending: Rest Create a Customer with Name: " + response.getEntity().getClass().getName());
return response;
}
CustomerResource-Code:
#Path("customers")
public class CustomerResource implements IAllowedMethods<Customer> {
private static final long serialVersionUID = -6367055402693237329L;
private Logger logger = Logger.getLogger(CustomerResource.class.getName());
#Inject
private CustomerService service;
public CustomerResource() {
logger.info("create of instance " + this.getClass().getName());
}
#Override
#GET
#Produces({ MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON })
public Response get() {
List<Customer> list = service.loadAll(Customer.FINDALL, Customer.class);
if (list != null && !list.isEmpty()) {
ResponseCustomerList responseList = new ResponseCustomerList();
responseList.setList(list);
return Response.ok(responseList).build();
}
return Response.status(Status.NOT_FOUND).build();
}
.
.
.
Customer Code:
import de.ostfalia.sep.adapter.XMLIntegerAdapter;
#XmlRootElement
#XmlAccessorType(XmlAccessType.FIELD)
public class Customer implements Serializable {
private static final long serialVersionUID = 80668466040239995L;
#XmlID
#XmlJavaTypeAdapter(XMLIntegerAdapter.class)
private Integer customerNumber;
private String customerName;
private String contactLastName;
private String contactFirstName;
private String phone;
private String addressLine1;
private String addressLine2;
private String city;
private String state;
private String postalCode;
private String country;
#XmlIDREF
private Employee salesRepEmployee;
private BigDecimal creditLimit;
private Set<Payment> payments;
private Set<Order> orders;
public Customer() {
}
public Customer(Integer customernumber) {
this.customerNumber = customernumber;
}
public Customer(Integer customerNumber, String customerName, String contactLastName, String contactFirstName,
String phone, String addressLine1, String city, String country) {
this.customerNumber = customerNumber;
this.customerName = customerName;
this.contactLastName = contactLastName;
this.contactFirstName = contactFirstName;
this.phone = phone;
this.addressLine1 = addressLine1;
this.city = city;
this.country = country;
}
public Integer getCustomerNumber() {
return customerNumber;
}
public void setCustomerNumber(Integer customerNumber) {
this.customerNumber = customerNumber;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getContactLastName() {
return contactLastName;
}
public void setContactLastName(String contactLastName) {
this.contactLastName = contactLastName;
}
public String getContactFirstName() {
return contactFirstName;
}
public void setContactFirstName(String contactFirstName) {
this.contactFirstName = contactFirstName;
}
public String getPhone() {
return phone;
}
public void setPhone(String phone) {
this.phone = phone;
}
public String getAddressLine1() {
return addressLine1;
}
public void setAddressLine1(String addressLine1) {
this.addressLine1 = addressLine1;
}
public String getAddressLine2() {
return addressLine2;
}
public void setAddressLine2(String addressLine2) {
this.addressLine2 = addressLine2;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
public String getState() {
return state;
}
public void setState(String state) {
this.state = state;
}
public String getPostalCode() {
return postalCode;
}
public void setPostalCode(String postalCode) {
this.postalCode = postalCode;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public Employee getSalesRepEmployee() {
return salesRepEmployee;
}
public void setSalesRepEmployee(Employee salesRepEmployee) {
this.salesRepEmployee = salesRepEmployee;
}
public BigDecimal getCreditLimit() {
return creditLimit;
}
public void setCreditLimit(BigDecimal creditLimit) {
this.creditLimit = creditLimit;
}
#Override
public int hashCode() {
int hash = 0;
hash += (customerNumber != null ? customerNumber.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 Customer)) {
return false;
}
Customer other = (Customer) object;
if ((this.customerNumber == null && other.customerNumber != null)
|| (this.customerNumber != null && !this.customerNumber.equals(other.customerNumber))) {
return false;
}
return true;
}
#Override
public String toString() {
return customerNumber.toString();
}
public Set<Payment> getPayments() {
return payments;
}
public void setPayments(Set<Payment> payments) {
this.payments = payments;
}
public Set<Order> getOrders() {
return orders;
}
public void setOrders(Set<Order> orders) {
this.orders = orders;
}
}
Instead of response.getEntity(), use response.readEntity(String.class) to get the data as a String. If you want to deserialize it to a POJO, then just pass that class to the readEntity.
Also you should make sure to check the status code (response.getStatus()) to make sure it's a success status.

JavaFX properties fail to persist

I'm using some JavaFX properties in my app:
#Entity(name = "Klanten")
#Table(name = "Klanten")
#NamedQueries({
#NamedQuery(name = "Klanten.findAll", query = "select k from Klanten k")
})
public class Klant implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int klantId;
#Transient
private final SimpleStringProperty naam = new SimpleStringProperty();
//private String naam;
//private String straat;
#Transient
private final SimpleStringProperty straat = new SimpleStringProperty();
private String telefoon;
private String huisnummer;
private String gsm;
private String woonplaats;
private String email;
private String postcode;
#OneToMany(mappedBy = "Klant", cascade = CascadeType.REMOVE)
private List<Raam> ramen;
public Klant() {
}
public Klant(String naam) {
this.naam.set(naam);
}
#Override
public String toString() {
return this.naam.get();
}
#Access(AccessType.PROPERTY)
#Column(name="naam")
public String getNaam() {
return this.naam.get();
}
public void setNaam(String naam){
this.naam.set(naam);
}
public List<Raam> getRamen() {
return this.ramen;
}
#Id
public int getKlantId() {
return klantId;
}
public void setKlantId(int klantId) {
this.klantId = klantId;
}
#Access(AccessType.PROPERTY)
#Column(name="straat")
public String getStraat() {
return straat.get();
}
public void setStraat(String straat) {
this.straat.set(straat);
}
public String getTelefoon() {
return telefoon;
}
public void setTelefoon(String telefoon) {
this.telefoon = telefoon;
}
public String getHuisnummer() {
return huisnummer;
}
public void setHuisnummer(String huisnummer) {
this.huisnummer = huisnummer;
}
public String getGsm() {
return gsm;
}
public void setGsm(String gsm) {
this.gsm = gsm;
}
public String getWoonplaats() {
return woonplaats;
}
public void setWoonplaats(String woonplaats) {
this.woonplaats = woonplaats;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPostcode() {
return postcode;
}
public void setPostcode(String postcode) {
this.postcode = postcode;
}
public StringProperty naamProperty() {
return naam;
}
public StringProperty straatProperty() {
return straat;
}
}
However when I let JPA generate my database, the column "naam" and "straat" aren't generated. I get no error. How can I resolve this?
I tried all the things listed here:
Possible solution 1
Possible solution 2
These didn't work.
You can try to use regular properties and then have another get method which returns a new SimpleStringProperty, i.e.:
public StringProperty naamProperty() {
return new SimpleStringProperty(naam);
}
public StringProperty straatProperty() {
return new SimpleStringProperty(straat);
}