Add Additional ObjectClass with Spring Data LDAP programmatically while creating - spring

is There a way to return the objectClasses when creating a Object in Spring Data LDAP programmatically?
I want to create a dataModel that most of the time has two objectClasses but occationally needs a third objectClass depending on the state of one attribute.
I Tried the following but it did not work:
#Setter
#Getter
#Entry(objectClasses={"objectClassA", "objectClassB"})
public class MyDataModel implements Persistable<Name>, Serializable {
#Transient
private static final long serialVersionUID = 4589047820223901953L;
/**
* DN der TechId im IDM-Vault
*/
#Id
private Name dn;
#Attribute(name = "objectClass")
private Set<String> objectClass;
//attribute of objectClassA
#Attribute(name = "attributeA")
private String attributeA;
//attribute of objectClassB
#Attribute(name = "attributeB")
private String attributeB;
//attribute of objectClassC
#Attribute(name = "attributeC")
private String attributeC;
public MyDataModel(){
}
public MyDataModel(Name dn, String attributeA){
this.isNew = true;
this.dn = dn;
this.attributeA = attributeA;
objectClass = new HashSet<String>();
objectClass.add("objectClassA");
objectClass.add("objectClassB");
if(attributeA.equals("some_value")){
objectClass.add("objectClassC");
}
}
public Set<String> getObjectClass() {
return objectClass;
}
}

Related

Hibernate JPA loop

I created an entity class :
#Entity
#Table(name="users")
#Getter #Setter
public class UserModel implements Serializable {
#Setter(AccessLevel.NONE)
#Getter(AccessLevel.NONE)
private static final long serialVersionUID = -5608230793232883579L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(nullable = false, unique = true)
private String userId;
#Column(nullable = false, length = 50)
private String firstName;
#Column(nullable = false, length = 50)
private String lastName;
#Email
#Column(nullable = false, length = 120, unique = true)
private String email;
#Column(nullable = false)
private String encryptedPassword;
private Boolean emailVerificationStatus = false;
private String emailVerificationToken;
#ManyToMany(cascade= { CascadeType.PERSIST }, fetch = FetchType.EAGER )
#JoinTable(
name = "user_role",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns=#JoinColumn(name = "role_id", referencedColumnName = "id"))
private List<RoleModel> roles;
#JsonManagedReference
#OneToMany(mappedBy = "user")
private List<ProjectModel> projects;
}
For the list of projects, I also have an entity class:
#Entity
#Table(name= "projects")
#Getter #Setter
public class ProjectModel implements Serializable {
#Setter(AccessLevel.NONE)
#Getter(AccessLevel.NONE)
public static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#Column(nullable = false, unique = true)
private String projectId;
// ...
#Column
#JsonManagedReference
#OneToMany(mappedBy = "project")
private List<ObjectiveModel> objectives;
// ...
#JsonBackReference
#ManyToOne(
cascade = { CascadeType.DETACH, CascadeType.MERGE, CascadeType.PERSIST, CascadeType.REFRESH },
fetch = FetchType.LAZY
)
private UserModel user;
}
I also use a DTO layer to communicate with database:
#Getter #Setter
public class UserDto implements Serializable {
#Setter(AccessLevel.NONE)
#Getter(AccessLevel.NONE)
private static final long serialVersionUID = -5352357837541477260L;
// contains more information than models used for rest
private long id;
private String userId;
private String firstName;
private String lastName;
private String email;
private String password;
private String encryptedPassword;
private String emailVerificationToken;
private Boolean emailVerificationStatus = false;
private List<String> roles;
private List<ProjectDto> projects;
}
Each entity has its own Dto equivalent. I can create a user. My issue is trying to log in. My userServiceImpl implements Spring Security UserService. Here is my implementation :
#Override
public UserDetails loadUserByUsername(String email) throws UsernameNotFoundException {
UserModel userModel = userRepository.findByEmail(email);
if(userModel == null)
throw new UsernameNotFoundException("User with email " + email + " not found");
return new UserPrincipalManager(userModel);
}
My UserPrincipalManager :
public class UserPrincipalManager implements UserDetails {
private static final long serialVersionUID = 7464059818443209139L;
private UserModel userModel;
private ProjectModel projectModel;
#Getter #Setter
private String userId;
#Autowired
public UserPrincipalManager(UserModel userModel) {
this.userModel = userModel;
this.userId = userModel.getUserId();
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Collection<GrantedAuthority> authorities = new HashSet<>();
Collection<AuthorityModel> authorityModelEntities = new HashSet<>();
// get user roles
Collection<RoleModel> roleModels = userModel.getRoles();
if (roleModels == null) {
return authorities; // null
}
// get user roles
roleModels.forEach((role) ->{
authorities.add(new SimpleGrantedAuthority(role.getName()));
authorityModelEntities.addAll(role.getAuthorities());
});
// get user authorities
authorityModelEntities.forEach(authorityModel -> {
authorities.add(new SimpleGrantedAuthority(authorityModel.getName()));
});
return authorities;
}
#Override
public String getPassword() {
return this.userModel.getEncryptedPassword();
}
#Override
public String getUsername() {
return this.userModel.getEmail();
}
// we do not store this information in DB
#Override
public boolean isAccountNonExpired() {
return true;
}
// we do not store this information in DB (yet)
#Override
public boolean isAccountNonLocked() {
return true;
}
// we do not store this information in DB (yet)
#Override
public boolean isCredentialsNonExpired() {
return true;
}
// isEnabled depending if account is activated => email verification status value
#Override
public boolean isEnabled() {
return this.userModel.getEmailVerificationStatus();
}
}
While trying to log in a User sql request is looping.
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:59)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:31)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:106)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:59)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:31)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:106)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:59)
at org.modelmapper.internal.converter.MergingCollectionConverter.convert(MergingCollectionConverter.java:31)
at org.modelmapper.internal.MappingEngineImpl.convert(MappingEngineImpl.java:303)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:110)
at org.modelmapper.internal.MappingEngineImpl.setDestinationValue(MappingEngineImpl.java:242)
at org.modelmapper.internal.MappingEngineImpl.propertyMap(MappingEngineImpl.java:188)
at org.modelmapper.internal.MappingEngineImpl.typeMap(MappingEngineImpl.java:152)
at org.modelmapper.internal.MappingEngineImpl.map(MappingEngineImpl.java:106)
In the end the application crashes and returns a 403 error.
2020-10-05 12:07:22.215 DEBUG 4564 --- [nio-8080-exec-8] o.s.s.w.a.ExceptionTranslationFilter : Access is denied (user is anonymous); redirecting to authentication entry point
org.springframework.security.access.AccessDeniedException: Access is denied
at org.springframework.security.access.vote.AffirmativeBased.decide(AffirmativeBased.java:84) ~[spring-security-core-5.3.3.RELEASE.jar:5.3.3.RELEASE]
The login fonction works if user do not have project associated.
I don't know anything about model mapper, but I would like to provide you an alternative solution because I think this is a perfect use case for Blaze-Persistence Entity Views.
I created the library to allow easy mapping between JPA models and custom interface or abstract class defined models, something like Spring Data Projections on steroids. The idea is that you define your target structure(domain model) the way you like and map attributes(getters) via JPQL expressions to the entity model.
A DTO model for your use case could look like the following with Blaze-Persistence Entity-Views:
#EntityView(UserModel.class)
public interface UserDto extends Serializable {
#IdMapping
Long getId();
String getUserId();
String getFirstName();
String getLastName();
String getEmail();
String getPassword();
String getEncryptedPassword();
String getEmailVerificationToken();
Boolean getEmailVerificationStatus();
Set<String> getRoles();
Set<ProjectDto> getProjects();
#EntityView(ProjectModel.class)
interface ProjectDto {
#IdMapping
Long getId();
String getProjectId();
// Other mappings...
}
}
Querying is a matter of applying the entity view to a query, the simplest being just a query by id.
UserDto a = entityViewManager.find(entityManager, UserDto.class, id);
The Spring Data integration allows you to use it almost like Spring Data Projections: https://persistence.blazebit.com/documentation/entity-view/manual/en_US/index.html#spring-data-features
The big bonus here, it will only fetch the columns that are actually needed and it validates the DTO model against your JPA model during boot time, so there are no more runtime surprises!

Issue mapping fields ModelMapper

I use DTO and modelMapper in order not to make visible some fields.
I have a CategoryEntity that can have subcategories
public class CategoryEntity {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private Long id;
#Column(length = 30, nullable = false)
private String categoryKeyId;
#Column(nullable = false)
private String name;
#ManyToOne(optional = true, fetch = FetchType.LAZY)
#JoinColumn(name="parent_id", nullable=true)
private CategoryEntity parentCategory;
// allow to delete also subcategories
#OneToMany(mappedBy="parentCategory", cascade = CascadeType.ALL)
private List<CategoryEntity> subCategories;
}
When i create a category I use a model:
#Getter #Setter
public class CategoryRequestModel {
private String name;
private String parentCategoryKeyId;
}
In this model i want parentCategoryKeyId to match with the categoryKeyId of the parent.
For example if i create a "top" category :
{
"name": "topCategory"
}
It returns me :
{
"categoryKeyId": "jUcpO27Ch2YrT2zkLr488Q435F8AKS",
"name": "topCategory",
"subCategories": null
}
When i do this :
{
"name": "sub",
"parentCategoryKeyId": "jUcpO27Ch2YrT2zkLr488Q435F8AKS"
}
In my Controller, i pass the rest object to a DTO Layer which calls a service :
public CategoryRestResponseModel createCategory(#RequestBody CategoryRequestModel categoryRequestModel) {
CategoryRestResponseModel returnValue = new CategoryRestResponseModel();
if( categoryRequestModel.getName().isEmpty())
throw new NullPointerException(ErrorMessages.MISSING_REQUIRED_FIELDS.getErrorMessage());
ModelMapper modelMapper = new ModelMapper();
CategoryDto categoryDto = modelMapper.map(categoryRequestModel, CategoryDto.class);
CategoryDto createdCategory = categoryService.createCategory(categoryDto);
returnValue = modelMapper.map(createdCategory, CategoryRestResponseModel.class);
return returnValue;
}
My CategoryDto is a basic POJO :
#Getter #Setter
public class CategoryDto implements Serializable {
#Getter(AccessLevel.NONE)
private static final long serialVersionUID = 1L;
private String categoryKeyId;
private String parentCategoryKeyId;
private String name;
private CategoryDto parentCategory;
private List<CategoryDto> subCategories;
}
In my Service :
public CategoryDto createCategory(CategoryDto categoryDto) {
//1. Create an empty object to return
System.out.println("Hello World");
CategoryDto returnValue = new CategoryDto();
System.out.println("CategoryDto: " + categoryDto);
// check if category exists
if (categoryRepository.findByName(categoryDto.getName()) != null)
throw new ApplicationServiceException("Record already in Database");
ModelMapper modelMapper = new ModelMapper();
CategoryEntity categoryEntity = modelMapper.map(categoryDto, CategoryEntity.class);
// Generate categoryKeyId
String categoryKeyId = utils.generateCategoryKeyId(30);
categoryEntity.setCategoryKeyId(categoryKeyId);
System.out.println("categoryDto parentCategory: " + categoryDto.getParentCategory());
System.out.println("CategoryDto: " + categoryDto);
if(categoryDto.getParentCategoryKeyId() != null) {
CategoryEntity parentCategory = categoryRepository.findByCategoryKeyId(categoryDto.getParentCategoryKeyId());
categoryEntity.setParentCategory(parentCategory);
System.out.println("CategoryEntity: " + categoryEntity);
System.out.println("parentCategory: " + parentCategory);
}
CategoryEntity storedCategory = categoryRepository.save(categoryEntity);
returnValue = modelMapper.map(storedCategory, CategoryDto.class);
return returnValue;
}
My issue is that I would like to save the subcategory and retrieve the ID that match the categoryKeyId ...
In the database my entry should be like this
My First entry should have:
id = 1 - parent_id = null, category_key_id = jUcpO27Ch2YrT2zkLr488Q435F8AKS, name = topCategory ...
AND :
id = 2 - parent_id = 1 , category_key_id = "another generated key", name= sub
Unfortunatelly I just persist the id, the categorykeyid and the name.
I removed id from CategoryDto and i obtain : 1) Converter org.modelmapper.internal.converter.NumberConverter#348fc3d8 failed to convert java.lang.String to java.lang.Long.
I solved it in a "dirty" way.
I just changed my object in entry and added a long id.
It gives me :
#Getter #Setter
public class CategoryRequestModel {
private Long id;
private String name;
private String parentCategoryKeyId;
}

JPA: ManyToMany issue - Spring Boot Project

I want to establish many-to-many relation between two table. One is called User and the other is Tag.
My goal is to add previously created Tag lists to newly created User objects. Tag must be added to the database first, and then merged with User after selecting from existing ones.
How can I solve this problem? Where am I doing wrong? Any advice?
Thank you.
All my codes are as follows.
Filename = Demo2Application.java
#SpringBootApplication
public class Demo2Application implements CommandLineRunner {
#Autowired
private UserService userService;
#Autowired
private TagService tagService;
public static void main(String[] args) {
SpringApplication.run(Demo2Application.class, args);
}
#Override
public void run(String... args) throws Exception {
//Scenario: Tag list is already created.
Tag tag1 = new Tag("strong", true); //id = 1
Tag tag2 = new Tag("weak", true); //id = 2
Tag tag3 = new Tag("nice", true); //id = 3
Tag tag4 = new Tag("clever", true); //id = 4
tagService.save(tag1);
tagService.save(tag2);
tagService.save(tag3);
tagService.save(tag4);
//Scenario: Defining a new user.
User user1 = new User("foo", "foo#gmail.com");
//Scenario: Appropriate predefined tags are being added to the new user object.
user1.addTag(tagService.findById(1));
user1.addTag(tagService.findById(4));
//Scenario: Registering a User object to the database.
userService.save(user1);
}
}
Filename = entity/Model.java
#MappedSuperclass
public class Model {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
#CreationTimestamp
private Date createdAt;
#UpdateTimestamp
private Date updatedAt;
// standard constructors, getters, and setters
}
Filename = entity/User.java
#Entity
#Table(name = "user")
public class User extends Model {
#Column(name = "name")
private String name;
#Column(name = "email")
private String email;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "user_tag",
joinColumns = {#JoinColumn(name = "user_id")},
inverseJoinColumns = {#JoinColumn(name = "tag_id")})
private List<Tag> tags = new ArrayList<>();
//
public void addTag(Tag tag) {
tags.add(tag);
}
// standard constructors, getters, and setters
Filename = entity/Tag.java
#Entity
#Table(name = "tag")
public class Tag extends Model {
#Column(name = "tag_name")
private String tagName;
#Column(name = "tag_active")
private boolean tagActive;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "user_tag",
joinColumns = {#JoinColumn(name = "tag_id")},
inverseJoinColumns = {#JoinColumn(name = "user_id")})
private List<User> users = new ArrayList<>();
// standard constructors, getters, and setters
Repositories = TagRepository, UserRepository
public interface UserRepository extends JpaRepository<User, Long> {
}
public interface TagRepository extends JpaRepository<Tag, Long> {
}
Filename = service/UserService.java
#Service
public class UserService {
private UserRepository userRepository;
#Autowired
public UserService(UserRepository userRepository) {
this.userRepository = userRepository;
}
public User findById(long id) {
Optional<User> result = userRepository.findById(id);
return result.orElse(null);
}
public void save(User user) {
userRepository.save(user);
}
}
Filename = service/TagService.java
#Service
public class TagService {
private TagRepository tagRepository;
#Autowired
public TagService(TagRepository tagRepository) {
this.tagRepository = tagRepository;
}
public Tag findById(long id) {
Optional<Tag> result = tagRepository.findById(id);
return result.orElse(null);
}
public void save(Tag tag) {
tagRepository.save(tag);
}
}
Filename = resources/application.properties
server.port=7070
## Database (PostgreSQL + Hikari + JPA)
spring.datasource.type=com.zaxxer.hikari.HikariDataSource
spring.datasource.hikari.connectionTimeout=20000
spring.datasource.hikari.maximumPoolSize=5
spring.datasource.hikari.minimum-idle=5
spring.datasource.hikari.idle-timeout=300000
spring.datasource.hikari.max-lifetime=1200000
#
spring.datasource.url=jdbc:postgresql://localhost:5432/demo
spring.datasource.username=admin
spring.datasource.password=1234
#
spring.jpa.hibernate.ddl-auto=create-drop
## Database ##

org.hibernate.PropertyAccessException: Could not set field value [1] value by reflection

Hi guys I am new to Spring and I am getting this error in my project:
org.hibernate.PropertyAccessException: Could not set field value [1] value by
reflection : [class com.**.domain.identities.NurseAgencyIdentity.agencyId]
setter of com.**.domain.identities.NurseAgencyIdentity.agencyId
There are some classes involved in this process: Nurse , Agency, Named(abstract), NurseAgency and NurseAgencyIdentity. There is a many-to-many relationship between Nurse--Agency with an extra column nurse record. The Named class is an abstract class that contains the fields id and name and is being used by many tables in my design being id the identifier of the descendant table. To implement the many-to-many I had to use the #Embeddable annotation in the last class NurseAgencyIdentity which is the id of my NurseAgency join table. Here is the code:
NurseAgencyIdentity
#Embeddable
#Data
public class NurseAgencyIdentity implements Serializable {
#Column(name="nurse_id")
private Long nurseId;
#Column(name="agency_id")
private Long agencyId;
#Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
NurseAgencyIdentity that = (NurseAgencyIdentity) o;
return Objects.equals(nurseId, that.nurseId) &&
Objects.equals(agencyId, that.agencyId);
}
#Override
public int hashCode() {
return Objects.hash(nurseId, agencyId);
}
}
NurseAgency
#Entity
#Data
public class NurseAgency {
#EmbeddedId
private NurseAgencyIdentity id;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("nurseId")
private Nurse nurse;
#ManyToOne(fetch = FetchType.LAZY)
#MapsId("agencyId")
private Agency agency;
private String nurseRecord;
}
Nurse
#Entity
#Data
public class Nurse {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String firstName;
private String lastName;
#Enumerated(EnumType.STRING)
private License license;
#OneToMany(mappedBy = "nurse", cascade = CascadeType.ALL, orphanRemoval = true)
private List<NurseAgency> agencies = new ArrayList<>();
// need the extra column
public void addAgency(Agency agency) {//, String nurseRecord) {
NurseAgency nurseAgency = new NurseAgency();
nurseAgency.setAgency(agency);
nurseAgency.setNurse(this);
//nurseAgency.setNurseRecord(nurseRecord);
agency.getNurses().add(nurseAgency);
}
public void removeAgency(Agency agency) {
for (Iterator<NurseAgency> iterator = agencies.iterator(); iterator.hasNext(); ) {
NurseAgency nurseAgency = iterator.next();
if (nurseAgency.getNurse().equals(this) && nurseAgency.getAgency().equals(agency)){
iterator.remove();
nurseAgency.getAgency().getNurses().remove(nurseAgency);
nurseAgency.setNurse(null);
nurseAgency.setAgency(null);
}
}
}
#Override
public String toString() {
return id + " " + firstName + " " + middleName + " " + lastName;
}
}
Named
#MappedSuperclass
#EntityListeners(AuditingEntityListener.class)
#Data
public abstract class Named implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
}
Agency
#Entity
#Data
public class Agency extends Named {
private String description;
#OneToMany(mappedBy = "agency", cascade = CascadeType.ALL, orphanRemoval = true)
private List<NurseAgency> nurses = new ArrayList<>();
}
And I am having this error when trying to seed the join table:
BootStrapData
#Component
public class BootStrapData implements CommandLineRunner {
#Autowired
private final NurseRepository nurseRepository;
#Autowired
private final AgencyRepository agencyRepository;
private final NurseAgencyRepository nurseAgencyRepository;
public BootStrapData(NurseRepository nurseRepository, AgencyRepository agencyRepository, NurseAgencyRepository nurseAgencyRepository) {
this.nurseRepository = nurseRepository;
this.agencyRepository = agencyRepository;
this.nurseAgencyRepository = nurseAgencyRepository;
}
#Override
public void run(String... args) throws Exception {
System.out.println("Loading agencies ");
ArrayList<Agency> agencies = GetAgencies();
System.out.println("Loading Nurses ");
ArrayList<Nurse> nurses = GetNurses(agencies);
nurses.stream().forEach( n -> nurseRepository.save(n));
agencies.stream().forEach( a -> agencyRepository.save(a));
//Nurses Agencies
ArrayList<NurseAgency> nurseAgencies = new ArrayList<>(1);
nurseAgencies.addAll(SetNurseAndAgencies(nurses.get(0), new Agency[]{agencies.get(0), agencies.get(1), agencies.get(2)}));
nurseAgencies.addAll(SetNurseAndAgencies(nurses.get(1), new Agency[]{agencies.get(0), agencies.get(1)}));
nurseAgencies.addAll(SetNurseAndAgencies(nurses.get(2), new Agency[]{agencies.get(1), agencies.get(2)}));
for (int i=0; i<nurseAgencies.size();i++){
nurseAgencyRepository.save(nurseAgencies.get(i)); // I've got the error in first iteration in this line
}
}
private ArrayList<Agency> GetAgencies() {
ArrayList<Agency> agencies = new ArrayList<>(3);
Agency a1 = new Agency();
a1.setName("Agency 1");
agencies.add(a1);
Agency a2 = new Agency();
a2.setName("Agency 2");
agencies.add(a2);
Agency a3 = new Agency();
a3.setName("Agency 3");
agencies.add(a3);
return agencies;
}
private ArrayList<Nurse> GetNurses(ArrayList<Agency> agencies) {
ArrayList<Nurse> nurses = new ArrayList<>(3);
Nurse n1 = new Nurse();
n1.setFirstName("Mario");
n1.setLastName("Perez");
nurses.add(n1);
Nurse n2 = new Nurse();
n2.setFirstName("Luis");
n2.setLastName("Ruiz");
nurses.add(n2);
Nurse n3 = new Nurse();
n3.setFirstName("Maria");
n3.setLastName("Crez");
nurses.add(n3);
return nurses;
}
private ArrayList<NurseAgency> SetNurseAndAgencies(Nurse nurse, Agency[] agencies) {
ArrayList<NurseAgency> nurseagencies = new ArrayList<>(agencies.length);
for (int i=0; i<agencies.length; i++){
NurseAgency na = new NurseAgency();
na.setNurse(nurse);
na.setAgency(agencies[i]);
na.setNurseRecord(nurse.getFirstName() + agencies[i].getName());
nurseagencies.add(na);
}
return nurseagencies;
}
}
Where is the problem?
Try changing the NurseAgencyIdentity declaration on NurseAgency from:
#EmbeddedId
private NurseAgencyIdentity id;
to:
#EmbeddedId
private NurseAgencyIdentity id = new NurseAgencyIdentity();
I didn't see the full stack trace but the root cause can be a NullPointerException when hibernate tries to set fields (generated agencyId [ 1 ] in your case) via reflection on NurseAgencyIdentity and it's null.
See org.hibernate.tuple.entity.AbstractEntityTuplizer#getIdentifier

Unable to get dependent object data after form submission in spring MVC

public class Employee implements IEmployee, Serializable {
private static final long serialVersionUID = 3539505455231361934L;
#Column(name="emp_Id", nullable=false)
private Integer emp_Id;
#Id
#GeneratedValue
#Column(name="login_Id", nullable=false)
private String login_Id;
#Column(name="password", nullable=false)
private String password;
#Column(name="first_name", nullable=false)
private String first_name;
#Column(name="last_name", nullable=false)
private String last_name;
#Column(name="email", nullable=false)
private String email;
#Column(name="address", nullable=false)
private String address;
#Column(name="mobile_Number", nullable=false)
private Integer mobile_Number;
#Column(name="create_Date", nullable=false)
private Date create_Date;
#Column(name="modified_Date", nullable=false)
private Date modified_Date;
#Column(name="security_Question")
private String security_Question;
#Column(name="security_Question_Answer")
private String security_Question_Answer;
#Column(name="login_Attempts")
private String login_Attempts;
#OneToMany(cascade=CascadeType.ALL,fetch=FetchType.EAGER)
#JoinTable(name="employe_role",
joinColumns = {#JoinColumn(name="login_Id")},
inverseJoinColumns = {#JoinColumn(name="role_Id")})
private Collection<Role> role;//need to change name --> Dependent Object Role
---settters and getters
}
Role
#Id
#GeneratedValue
#Column(name="role_Id")
private Integer role_Id;
#Column(name="role_Code", nullable=false)
private String role_Code;
#Column(name="role_Name", nullable=false)
private String role_Name;
#Column(name="discription", nullable=false)
private String discription;
#Column(name="created_Date")
private Date created_Date;
#Column(name="modified_Date")
private Date modified_Date;
JSP form
<form:form name="register-employee" action="/registerEmployee" method="post" commandName="employee">
<c:forEach var="role" varStatus="statusEmpRole" items="${employee.role}">
<form:hidden path="role[${statusEmpRole.index}].role_Name" value="${role.role_Name}" />
<form:checkbox path="role[${statusEmpRole.index}].role_Name" value="${role.role_Name}" itemValue="role.role_Id" />
<c:out value="${role.role_Name}" /><br>
Controller
For displaying the form
#Override
#RequestMapping(value="/employeeregistrationform", method = RequestMethod.GET)
public ModelAndView employeeRegistrationForm(#ModelAttribute("employee") Employee employee, Model map) throws HibernateException, RoleNotFoundException {
IEmployee iEmployee = new Employee();
Collection<Role> collectionRoles= IRoleService.getLookUpRoles();
for (Role role : collectionRoles) {
LOGGER.info("roel {}",role.getRole_Name());
}
iEmployee.setFirst_name("helloooooo");
iEmployee.setRole(collectionRoles);
return new ModelAndView("registerEmploye", "employee", iEmployee);
}
Get the Submitted form Data
#Override
#RequestMapping(value="/registerEmployee",method=RequestMethod.POST)
public ModelAndView registerEmployee(#ModelAttribute("employee")Employee employee, BindingResult result) {
LOGGER.info("Registering Employe {}",employee.getFirst_name());
LOGGER.info("Selected Role Employe {}",employee.getRole());
ModelAndView model = new ModelAndView();
model.setViewName("registerEmploye");
return model;
}
employee.getRole() is getting null
my case is employee having multiple roles. let say admin and Projectmanager. while creating employee admin may select the roles(these are come from database) after submitting the employee registration from i'm getting role object is null.
please help me in this. Am i missing any thing here like property editor or init binder. if so please give me example how to use them.
Thanks
after Google i find the answer
I create Init Binder
#InitBinder
public void bindForm(WebDataBinder binder) {
binder.registerCustomEditor(Collection.class, new RoleEditor(Collection.class,true));
}
And i supply CustomCollectionEditor to that i.e RoleEditor
package com.evoke.tms.util;
import java.util.HashSet;
import java.util.Set;
import org.springframework.beans.propertyeditors.CustomCollectionEditor;
import com.evoke.tms.model.Role;
public class RoleEditor extends CustomCollectionEditor {
private Set<Role> roles;
public RoleEditor(Class collectionType, boolean nullAsEmptyCollection) {
super(collectionType, true);
}
public void setValue( Object object ){
if(object!=null&&object instanceof String)
System.out.println("Object is of type - " + object.getClass().getCanonicalName());
String[] roleIds = (String[])object;
roles=new HashSet<Role>();
if(roleIds!=null && roleIds.length>0)
for( int i=0; i<roleIds.length; i++ ){
try {
int id = Integer.parseInt(roleIds[i]);
Role role = new Role();
role.setRole_Id(id);
roles.add(role);
}catch( NumberFormatException ne ){}
}
}
public Object getValue(){
System.out.println("Roles are - " + roles);
return roles;
}
}
And i'm still confused how it is working
can any one help on this...

Resources