In my current spring project, the atributes from my entity classes have annotations to indicate which type of form control should be used for data input, like this:
#Column(name = "login", unique=true)
#Order(value=1)
#Input(name="login")
private String login;
#Column(name = "senha")
#Order(value=2)
#Input(type="password", name="senha")
private String senha;
#Column(name="nome")
#Order(value=3)
#Input(name="nome")
private String nome;
#Column(name="sobrenome")
#Order(value=4)
#Input(name="sobrenome")
private String sobrenome;
#Column(name="email")
#Order(value=5)
#Input(name="email")
private String email;
And I have custom tags which should read the atributes of the annotations and add to the page the correct tag, like that:
public class InputTag extends TagSupport {
/**
*
*/
private static final long serialVersionUID = 1L;
public void doTag() throws IOException, NoSuchFieldException, SecurityException {
JspWriter out = pageContext.getOut();
String name = this.getName();
String type = this.getType();
String pattern = this.getPattern();
if(type == null) {
if(pattern == "") {
out.println("<form:input path=\""+name+"\" class=\"form-control\"/>");
} else {
out.println("<form:input path=\""+name+"\" class=\"form-control valida\" pattern=\""+pattern+"\"/>");
}
} else {
if(pattern == "") {
out.println("<form:input path=\""+name+"\" type=\""+type+"\" class=\"form-control\"/>");
} else {
out.println("<form:input path=\""+name+"\" type=\""+type+"\" class=\"form-control valida\" pattern=\""+pattern+"\"/>");
}
}
}
...
}
the getter methods from the tag class have this format:
private String getName() throws NoSuchFieldException, SecurityException {
Field field = null;
Annotation annotation = field.getAnnotation(Input.class);
Input inputAnnotation = (Input) annotation;
String name = inputAnnotation.name();
return name;
}
What I need right now it's a way of store in the variable field the field I want add to he page. I know the method for do this if I was inside the entity class (something like getClass().getField("<nome>")), but how I access this information from my tag class?
The view is mapped in my controller this way:
#RequestMapping(value="cadastra")
#PreAuthorize("hasPermission(#user, 'cadastra_'+#this.this.name)")
public String cadastra(Model model) throws InstantiationException, IllegalAccessException {
model.addAttribute("command", this.entity.newInstance());
return "private/cadastrar";
}
and the jsp code in this moment it's this (just the basic structure):
<c:url value="/${entity}/cadastra" var="cadastra"/>
<form:form method="POST" action="${cadastra}" class="form" enctype="multipart/form-data">
<button type="submit" class="btn btn-lg btn-primary">cadastrar</button>
</form:form>
Anyone knows a way to accomplish this?
Related
I've read the same problem solutions, but it didn't helped me.
there is a part of my Bean class with good written getter:
#Entity
#Table(name = "notes")
public class Note {
#Id
#GeneratedValue (strategy = GenerationType.IDENTITY)
#Column (name = "id")
private int id;
#Column (name = "content")
private String content;
public Note() {
}
public Note(String title, String content, GregorianCalendar date, boolean done) {
this.title = title;
this.content = content;
this.date = date;
this.done = done;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getContent() {
return content;
}
public void setContent(String content) {
this.content = content;
}
}
Using debug mode i can see, that i've got my ArrayList of notes from dataBase. It means, that connection is good. there is a code from servlet:
public static final String OUTPUT_LIST = "List For Pager";
// other code, not nessesary for showing
protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
Integer pageNumber = (Integer) req.getAttribute(PAGE_NUMBER);
if(pageNumber==null) pageNumber = 1;
ArrayList<Note> result = new ArrayList<Note>();
ArrayList<Note> notes = DaoDriver.getActualNotesHandler().getNotesList();
//iteration method for filling result
fillListForPage(pageNumber,notes,result);
req.setAttribute(OUTPUT_LIST,result);
RequestDispatcher requestDispatcher = req.getRequestDispatcher("/index_test.jsp");
requestDispatcher.forward(req,resp);
There is a place, where i call my list from jsp:
<c:forEach var="note" items="${MainServlet.OUTPUT_LIST}">
<div class="row" padding="5" >
<div class="card-deck">
<div class="card">
<div class="card-header">Title1</div>
<div class="card-body"><p>${note.content}</p></div>
<div class="card-footer">
<input type="checkbox" class="Done">
<label>Done</label>
<button>Edit Note</button>
</div>
</div>
</c:forEach>
i have additional problem here, that can crash my application. I have the same situation, like in this question:
JPA Cannot resolve column/IntelliJ
but i have my data associated and quick fix doesn't resolve this problem.
what is wrong with my code?
UPD: I've fixed this problem by changing 2 strings:
req.setAttribute("list",result);
and
<c:forEach var="note" items="${list}">
And that's why i have new question: why can't i use the staic final string value (constant) from MainServlet.class for the key of request's property?
Try changing ${MainServlet.OUTPUT_LIST} to ${requestScope.OUTPUT_LIST}
<c:forEach var="note" items="${requestScope.OUTPUT_LIST}">
Recently we fixed the struts2's 'S2-045' problem.I updated all the struts2 related jar files including freemarker, ognl, xWork,etc. I use tomcat8 to deploy my dynamic web project. There were not any Exceptions while starting the tomcat-server. But some problems seemed occur: some values(got from db) should be displayed on the jsp pages dose not show up any more. There is no Exceptions thrown. I also can watch that I have already got the very Objects correctly in the Action Classes.
the following is some examples
// index.jsp ----- here is the list I want to show on the page.
// the list is the type of List<News> (Class News is my bussiness Class).
// I want to get the 'fTitle' and 'fCreatetime_s' from 'News' but they
// do not show up! (This used to be working very well.)
<s:bean name="org.ulibrary.web.Getarclist">
<s:iterator value="list">
<li>
<span class="listTitle">
<a target="_blank" href="ViewArc.action? uuid=${UUID}">${fTitle}</a>
</span>
<span class="listDate">${fCreatetime_s}</span>
</li>
</s:iterator>
</s:bean>
//=================================================================
Following is the ralated fields id News.java
// News.java (**just some ralated fields**)
class News{
#Id
#GeneratedValue(generator = "system-uuid")
#GenericGenerator(name = "system-uuid", strategy = "uuid")
#Column(name = "f_uuid", length = 32, unique = true)
private String UUID;
#Column(name = "f_title", length = 200)
private String fTitle;
#Transient
private String fCreatetime_s;
public String getUUID() {
return UUID;
}
public void setUUID(String uuid) {
UUID = uuid;
}
public String getFTitle() {
return fTitle;
}
public void setFTitle(String title) {
fTitle = title;
}
public String getFCreatetime_s() {
SimpleDateFormat formatter = new SimpleDateFormat("yyyy-MM-dd");
return formatter.format(Long.valueOf(fCreatetime));
}
public void setFCreatetime_s(String createtime_s) {
fCreatetime_s = createtime_s;
}
}
and then the GetarcList.java
//GetarcList.java (just include some related fields)
class GetarcList{
private List list;
public void setList(List list) {
this.list = list;
}
//!!!!!!$$$$$$$$--- Attention -----$$$$$$$$$!!!!!!!!!!!
// this method returns a List<News> , I can successfully get every value of 'News' in the list
public List getList() throws AuctionException{
String orderby_str = (String) OrderByMap.get(String.valueOf(orderby));
list = webTagManager.getArcList(row, typeid, titlelen, infolen, orderby_str + " " + orderway);
return list;
}
}
I think this maybe caused by the OGNL or JSP related jar-files. I didn't find any problems in my index.jsp or java-files.
You need to use getters/setters in the following format. Properties with only one starting lowercase letter are not uppercased.
public String getfTitle() {
return fTitle;
}
public void setfTitle(String title) {
fTitle = title;
}
Good morning all...
I have my application with Spring MVC which was working well.. Than I added a new field in a table, updated my model, but I'm getting the error in the title.
I'm getting the error only in the list view, in the detail page, with the same syntax, it works...
My model
#Entity
#Table(name="luci", catalog="SMARTPARK", uniqueConstraints = #UniqueConstraint(columnNames = "id_luce"))
public class Luce implements java.io.Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private int idLuce;
private Integer numeroLuce;
private String nomeLuce;
private String descrizione;
private boolean stato;
private Client client;
private boolean isOnline;
public Luce(){}
public Luce(int idLuce, Integer numeroLuce, String nomeLuce, String descrizione, boolean stato, Client client, boolean isOnline){
this.idLuce = idLuce;
this.numeroLuce = numeroLuce;
this.nomeLuce = nomeLuce;
this.client = client;
this.descrizione = descrizione;
this.stato = stato;
this.isOnline = isOnline;
}
#NotNull
#Id
#GeneratedValue
#Column(name="id_luce", unique = true, nullable = false)
public int getIdLuce() {
return idLuce;
}
public void setIdLuce(int idLuce) {
this.idLuce = idLuce;
}
#NotNull
#Column(name="numero_luce", unique = true, nullable = false)
public Integer getNumeroLuce() {
return numeroLuce;
}
public void setNumeroLuce(Integer numeroLuce) {
this.numeroLuce = numeroLuce;
}
#NotEmpty
#Size(max=50)
#Column(name="nome_luce", unique = true, nullable = false)
public String getNomeLuce() {
return nomeLuce;
}
public void setNomeLuce(String nomeLuce) {
this.nomeLuce = nomeLuce;
}
#ManyToOne
#JoinColumn(name="client")
public Client getClient() {
return this.client;
}
public void setClient(Client client) {
this.client = client;
}
#Size(max=255)
#Column(name="descrizione")
public String getDescrizione() {
return descrizione;
}
public void setDescrizione(String descrizione) {
this.descrizione = descrizione;
}
#Column(name="stato")
public boolean isStato() {
return stato;
}
public void setStato(boolean stato) {
this.stato = stato;
}
#Column(name="is_online")
public boolean isOnline() {
return isOnline;
}
public void setOnline(boolean isOnline) {
this.isOnline = isOnline;
}
}
then in the controller I have a simple
#RequestMapping(value = { path }, method = RequestMethod.GET)
public String listSpots(ModelMap model) {
List<Luce> luce = luceService.showLights();
model.addAttribute("luce", luce);
return path + "/luci";
}
which worked until this morning...
The view part is
<c:forEach items="${luce}" var="light">
<tbody>
<tr>
<td><div class="list-field">${light.numeroLuce}</div></td>
<td><div class="list-field">${light.nomeLuce}</div></td>
<td><div class="list-field">${light.client.nomeClient}</div></td>
<td><span class="text-success">
<c:choose>
<c:when test="${light.stato == true}" ><span class="glyphicon glyphicon-ok-sign"></span></c:when>
<c:otherwise><span class="text-danger"><span class="glyphicon glyphicon-remove-sign"></span></span></c:otherwise>
</c:choose>
</span></td>
<td><span class="text-success">
<c:choose>
<c:when test="${light.isOnline == true}" ><span class="glyphicon glyphicon-ok-sign"></span></c:when>
<c:otherwise><span class="text-danger"><span class="glyphicon glyphicon-remove-sign"></span></span></c:otherwise>
</c:choose>
</span></td>
<td class="actions"><a class="pull-right" href="<c:url value='/lights/${light.idLuce}' />"><span class="glyphicon glyphicon-edit"></span></a></td>
</tr>
</c:forEach>
I just added the light.isOnline == true part, and got the error.
Just to say that in another view I have the details of the single light, and it works..
The issue is with the bean method isOnline().
Change the method name to - getIsOnline() and it should work fine.
When you use expression language, it automatically appends get and capitalize first character of the variable to get to the getter method. There is no getIsOnline() method in your bean and the reason for this error.
EDIT:
As per java bean variable naming specs, change the name of the boolean field to online and then the isOnline() method will work fine.
The problem is your test expression.
<c:when test="${light.isOnline == true}"
You expect a property isOnline and test it for true. However there is no online property there is an property called isOnline, which would lead to a "getter" of isIsOnline instead.
Also testing it for true isn't really needed as that is the point of the test attribute.
Basically rewriting to the following should make it work
<c:when test="${light.isIsonline}"
This will look for a property isOnline and because it is a boolean and not a Boolean it will call the isIsOnline method in your class. If you don't want to you need to explicitly call the method and if that is doable depends on the EL version you are using.
<c:when test="${light.isOnline()}"
I am trying to map a collection of objects in Spring MVC but its giving error
Mapping of String is working fine but could not map a collection
org.springframework.beans.NotReadablePropertyException: Invalid property 'familyHistory[0].relation' of bean class [com.medicine.yourmedics.model.FamilyHistoryForm]: Field 'familyHistory[0].relation' does not exist
My Jsp file looks like
<form:form action="familyhistory" modelAttribute="familyhistoryform" method="POST" name="familyHistoryForm">
<table id="tblData">
<c:forEach items="${familyhistoryform.familyHistory}" varStatus="i">
<form:input path="familyHistory[${i.index}].relation" type="text" id="relation${i.index}"/>
</c:forEach>
The familyhistoryform is a wrapper around the familyHistory class.
public class FamilyHistoryForm {
public List<FamilyHistory> familyHistory = new LinkedList<FamilyHistory>();
public List<FamilyHistory> getFamilyHistory() {
return familyHistory;
}
public void setFamilyHistory(List<FamilyHistory> familyHistory) {
this.familyHistory = familyHistory;
}}
Family history pojo looks like
public class FamilyHistory {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id", unique = true, nullable = false)
private int id;
private String relation;
public String getRelation() {
return relation;
}
public void setRelation(String relation) {
this.relation = relation;
}}
Just for testing purpose have created a controller which returns a list of familyhistory objects
#RequestMapping(method = RequestMethod.GET, value = "/familyhistory")
public String viewRegistration(Map<String, Object> model,
HttpServletRequest request) {
List<FamilyHistory> familyHistoryList = new LinkedList<FamilyHistory>();
FamilyHistoryForm familyHistoryForm = new FamilyHistoryForm();
familyHistoryList.add(new FamilyHistory());
familyHistoryList.add(new FamilyHistory());
familyHistoryList.add(new FamilyHistory());
familyHistoryList.add(new FamilyHistory());
familyHistoryForm.setFamilyHistory(familyHistoryList);
model.put("familyhistoryform", familyHistoryForm);
return "familyhistory";
}
If in the jsp I write the path for the form input as path="familyHistory" then it prints the string array of familyhistory objects in the input text
[com.medicine.yourmedics.model.FamilyHistory#472c6818,
com.medicine.yourmedics.model.FamilyHistory#34662429,
com.medicine.yourmedics.model.FamilyHistory#1dd01a9f,
com.medicine.yourmedics.model.FamilyHistory#4983cc03]
In a spring mvc web application using hibernate in eclipse and tomcat server, I changed a couple of text fields to drop down lists in a jsp, so that a person's gender and race can each be selected from its own drop down menu. I was careful to change other levels of the application, including setting up joined tables for gender and race in the underlying database, and changing code in the model and repository levels. The application compiles, and the jsp loads with the correct selected values for the selected person in each dropdown list, but clicking the submit/update button causes a BindingResult.hasErrors() problem which does not help me localize the cause of the problem.
Can someone help me find the cause of the failure to process the update?
Here is the processUpdatePatientForm() method that is called in the controller class. Note that it triggers the System.out.println() which shows that BindingResult.hasErrors() and returns the jsp:
#RequestMapping(value = "/patients/{patientId}/edit", method = RequestMethod.PUT)
public String processUpdatePatientForm(#Valid Patient patient, BindingResult result, SessionStatus status) {
if (result.hasErrors()) {
System.out.println(":::::::::::::::: in PatientController.processUpdatePatientForm() result.hasErrors() ");
List<ObjectError> errors = result.getAllErrors();
for(int i=0;i<result.getErrorCount();i++){System.out.println("]]]]]]] error "+i+" is: "+errors.get(i).toString());}
return "patients/createOrUpdatePatientForm";}
else {
this.clinicService.savePatient(patient);
status.setComplete();
return "redirect:/patients?patientID=" + patient.getId();
}
}
When the jsp is returned, the following error messages are included:
//This is printed out in my jsp below the Sex drop down list:
Failed to convert property value of type java.lang.String to required type org.springframework.samples.knowledgemanager.model.Gender for property sex; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.samples.knowledgemanager.model.Gender] for property sex: no matching editors or conversion strategy found
//This is printed out in my jsp below the Race drop down list:
Failed to convert property value of type java.lang.String to required type org.springframework.samples.knowledgemanager.model.Race for property race; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.samples.knowledgemanager.model.Race] for property race: no matching editors or conversion strategy found
The following is all that is printed in the eclipse console:
Hibernate: select gender0_.id as id1_2_, gender0_.name as name2_2_ from gender gender0_ order by gender0_.name
Hibernate: select race0_.id as id1_7_, race0_.name as name2_7_ from race race0_ order by race0_.name
:::::::::::::::: in PatientController.processUpdatePatientForm() result.hasErrors()
]]]]]]] error 0 is: Field error in object 'patient' on field 'race': rejected value [Hispanic]; codes [typeMismatch.patient.race,typeMismatch.race,typeMismatch.org.springframework.samples.knowledgemanager.model.Race,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [patient.race,race]; arguments []; default message [race]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.samples.knowledgemanager.model.Race' for property 'race'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.samples.knowledgemanager.model.Race] for property 'race': no matching editors or conversion strategy found]
]]]]]]] error 1 is: Field error in object 'patient' on field 'sex': rejected value [Male]; codes [typeMismatch.patient.sex,typeMismatch.sex,typeMismatch.org.springframework.samples.knowledgemanager.model.Gender,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [patient.sex,sex]; arguments []; default message [sex]]; default message [Failed to convert property value of type 'java.lang.String' to required type 'org.springframework.samples.knowledgemanager.model.Gender' for property 'sex'; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [org.springframework.samples.knowledgemanager.model.Gender] for property 'sex': no matching editors or conversion strategy found]
Note that the values [Hispanic] and [Male] are shown in the error message as triggering the error. The problem might be that the name property of Gender and Race is being passed to Spring MVC, when the id property should be passed instead. But how do I fix this in the code?
Can someone help me get to the bottom of this? The first step would be how can I get a more useful error message which locates the location in my code where the problem is being triggered.
EDIT:
Per Sotirios's request, the following is my form in the jsp:
<form:form modelAttribute="patient" method="${method}" class="form-horizontal" id="add-patient-form">
<petclinic:inputField label="First Name" name="firstName"/>
<petclinic:inputField label="Middle Initial" name="middleInitial"/>
<petclinic:inputField label="Last Name" name="lastName"/>
<div class="control-group">
<petclinic:selectField label="Sex" name="sex" names="${genders}" size="5"/>
</div>
<petclinic:inputField label="Date of Birth" name="dateOfBirth"/>
<div class="control-group">
<petclinic:selectField label="Race" name="race" names="${races}" size="5"/>
</div>
<div class="form-actions">
<c:choose>
<c:when test="${patient['new']}">
<button type="submit">Add Patient</button>
</c:when>
<c:otherwise>
<button type="submit">Update Patient</button>
</c:otherwise>
</c:choose>
</div>
</form:form>
And the Patient.java class is:
#Entity
#Table(name = "patients")
public class Patient extends BaseEntity {
#OneToMany(cascade = CascadeType.ALL, mappedBy = "patient", fetch=FetchType.EAGER)
private Set<Document> documents;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "patient", fetch=FetchType.EAGER)
private Set<Address> addresses;
#OneToMany(cascade = CascadeType.ALL, mappedBy = "patient", fetch=FetchType.EAGER)
private Set<PhoneNumber> phonenumbers;
#Column(name = "first_name")
#NotEmpty
protected String firstName;
#Column(name = "middle_initial")
protected String middleInitial;
#Column(name = "last_name")
#NotEmpty
protected String lastName;
#ManyToOne
#JoinColumn(name = "sex_id")
protected Gender sex;
#Column(name = "date_of_birth")
#Type(type = "org.jadira.usertype.dateandtime.joda.PersistentDateTime")
#DateTimeFormat(pattern = "yyyy/MM/dd")
protected DateTime dateOfBirth;
#ManyToOne
#JoinColumn(name = "race_id")
protected Race race;
////////////// Document methods
protected void setDocumentsInternal(Set<Document> documents) {this.documents = documents;}
public Set<Document> getFaxes() {
Set<Document> faxes = new HashSet<Document>();
for (Document doc : getDocumentsInternal()) {if (doc.getType().getName().equals("ScannedFaxes")) {faxes.add(doc);}}
return faxes;
}
public Set<Document> getForms() {
Set<Document> forms = new HashSet<Document>();
for (Document doc : getDocumentsInternal()) {if (doc.getType().getName().equals("ScannedPatientForms")) {forms.add(doc);}}
return forms;
}
protected Set<Document> getDocumentsInternal() {
if (this.documents == null) {this.documents = new HashSet<Document>();}
return this.documents;
}
public List<Document> getDocuments() {
List<Document> sortedDocuments = new ArrayList<Document>(getDocumentsInternal());
PropertyComparator.sort(sortedDocuments, new MutableSortDefinition("name", true, true));
return Collections.unmodifiableList(sortedDocuments);
}
public void addDocument(Document doc) {
getDocumentsInternal().add(doc);
doc.setPatient(this);
}
public Document getDocument(String name) {return getDocument(name, false);}
/** Return the Document with the given name, or null if none found for this Patient.
* #param name to test
* #return true if document name is already in use
*/
public Document getDocument(String name, boolean ignoreNew) {
name = name.toLowerCase();
for (Document doc : getDocumentsInternal()) {
if (!ignoreNew || !doc.isNew()) {
String compName = doc.getName();
compName = compName.toLowerCase();
if (compName.equals(name)) {
return doc;
}
}
}
return null;
}
//////////// Address methods
protected void setAddressesInternal(Set<Address> addresses) {this.addresses = addresses;}
protected Set<Address> getAddressesInternal() {
if (this.addresses == null) {this.addresses = new HashSet<Address>();}
return this.addresses;
}
public List<Address> getAddresses() {
List<Address> sortedAddresses = new ArrayList<Address>(getAddressesInternal());
PropertyComparator.sort(sortedAddresses, new MutableSortDefinition("address", true, true));
return Collections.unmodifiableList(sortedAddresses);
}
public void addAddress(Address addr) {
getAddressesInternal().add(addr);
addr.setPatient(this);
}
public Address getAddress(String address) {return getAddress(address, false);}
/** Return the Address with the given name, or null if none found for this Patient.
* #param name to test
* #return true if document name is already in use
*/
public Address getAddress(String addr, boolean ignoreNew) {
addr = addr.toLowerCase();
for (Address address1 : getAddressesInternal()) {
if (!ignoreNew || !address1.isNew()) {
String compName = address1.getAddress();
compName = compName.toLowerCase();
if (compName.equals(addr)) {
return address1;
}
}
}
return null;
}
//////////// PhoneNumber methods
protected void setPhoneNumbersInternal(Set<PhoneNumber> phonenumbers) {this.phonenumbers = phonenumbers;}
protected Set<PhoneNumber> getPhoneNumbersInternal() {
if (this.phonenumbers == null) {this.phonenumbers = new HashSet<PhoneNumber>();}
return this.phonenumbers;
}
public List<PhoneNumber> getPhoneNumbers() {
List<PhoneNumber> sortedPhoneNumbers = new ArrayList<PhoneNumber>(getPhoneNumbersInternal());
PropertyComparator.sort(sortedPhoneNumbers, new MutableSortDefinition("phonenumber", true, true));
return Collections.unmodifiableList(sortedPhoneNumbers);
}
public void addPhoneNumber(PhoneNumber pn) {
getPhoneNumbersInternal().add(pn);
pn.setPatient(this);
}
public PhoneNumber getPhoneNumber(String pn) {return getPhoneNumber(pn, false);}
/** Return the PhoneNumber with the given name, or null if none found for this Patient.
* #param name to test
* #return true if phone number is already in use
*/
public PhoneNumber getPhoneNumber(String pn, boolean ignoreNew) {
pn = pn.toLowerCase();
for (PhoneNumber number : getPhoneNumbersInternal()) {
if (!ignoreNew || !number.isNew()) {
String compName = number.getPhonenumber();
compName = compName.toLowerCase();
if (compName.equals(pn)) {
return number;
}
}
}
return null;
}
public String getFirstName(){return this.firstName;}
public void setFirstName(String firstName){this.firstName = firstName;}
public String getMiddleInitial() {return this.middleInitial;}
public void setMiddleInitial(String middleinitial) {this.middleInitial = middleinitial;}
public String getLastName() {return this.lastName;}
public void setLastName(String lastName) {this.lastName = lastName;}
public Gender getSex() {return this.sex;}
public void setSex(Gender sex) {this.sex = sex;}
public void setDateOfBirth(DateTime birthDate){this.dateOfBirth = birthDate;}
public DateTime getDateOfBirth(){return this.dateOfBirth;}
public Race getRace() {return this.race;}
public void setRace(Race race) {this.race = race;}
#Override
public String toString() {
return new ToStringCreator(this)
.append("id", this.getId())
.append("new", this.isNew())
.append("lastName", this.getLastName())
.append("firstName", this.getFirstName())
.append("middleinitial", this.getMiddleInitial())
.append("dateofbirth", this.dateOfBirth)
.toString();
}
}
SECOND EDIT:
Per Alexey's comment, the following is the method in the controller class which has always had the #InitBinder annotation. It is identical to a method in the controller of a similar module which works:
#InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {dataBinder.setDisallowedFields("id");}
THIRD EDIT:
PatientController.java:
#Controller
#SessionAttributes(types = Patient.class)
public class PatientController {
private final ClinicService clinicService;
#Autowired
public PatientController(ClinicService clinicService) {this.clinicService = clinicService;}
#ModelAttribute("genders")
public Collection<Gender> populateGenders() {return this.clinicService.findGenders();}
#ModelAttribute("races")
public Collection<Race> populateRaces() {return this.clinicService.findRaces();}
#InitBinder
public void setAllowedFields(WebDataBinder dataBinder) {dataBinder.setDisallowedFields("id");}
#RequestMapping(value = "/patients/new", method = RequestMethod.GET)
public String initCreationForm(Map<String, Object> model) {
Patient patient = new Patient();
model.put("patient", patient);
return "patients/createOrUpdatePatientForm";
}
#RequestMapping(value = "/patients/new", method = RequestMethod.POST)
public String processCreationForm(#Valid Patient patient, BindingResult result, SessionStatus status) {
if (result.hasErrors()) {return "patients/createOrUpdatePatientForm";}
else {
this.clinicService.savePatient(patient);
status.setComplete();
return "redirect:/patients?patientID=" + patient.getId();
}
}
#RequestMapping(value = "/patients", method = RequestMethod.GET)
public String processFindForm(#RequestParam("patientID") String patientId, Patient patient, BindingResult result, Map<String, Object> model) {
Collection<Patient> results = this.clinicService.findPatientByLastName("");
model.put("selections", results);
int patntId = Integer.parseInt(patientId);
Patient sel_patient = this.clinicService.findPatientById(patntId);//I added this
model.put("sel_patient",sel_patient);
return "patients/patientsList";
}
#RequestMapping(value = "/patients/{patientId}/edit", method = RequestMethod.GET)
public String initUpdatePatientForm(#PathVariable("patientId") int patientId, Model model) {
Patient patient = this.clinicService.findPatientById(patientId);
model.addAttribute(patient);
return "patients/createOrUpdatePatientForm";
}
#RequestMapping(value = "/patients/{patientId}/edit", method = RequestMethod.PUT)
public String processUpdatePatientForm(#Valid Patient patient, BindingResult result, SessionStatus status) {
if (result.hasErrors()) {
System.out.println(":::::::::::::::: in PatientController.processUpdatePatientForm() result.hasErrors() ");
List<ObjectError> errors = result.getAllErrors();
for(int i=0;i<result.getErrorCount();i++){System.out.println("]]]]]]] error "+i+" is: "+errors.get(i).toString());}
return "patients/createOrUpdatePatientForm";}
else {
this.clinicService.savePatient(patient);
status.setComplete();
return "redirect:/patients?patientID=" + patient.getId();
}
}
}
FOURTH EDIT:
Gender.java
#Entity
#Table(name = "gender")
public class Gender extends NamedEntity {}
NamedEntity.java:
#MappedSuperclass
public class NamedEntity extends BaseEntity {
#Column(name = "name")
private String name;
public void setName(String name) {this.name = name;}
public String getName() {return this.name;}
#Override
public String toString() {return this.getName();}
}
BaseEntity.java:
#MappedSuperclass
public class BaseEntity {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
protected Integer id;
public void setId(Integer id) {this.id = id;}
public Integer getId() {return id;}
public boolean isNew() {return (this.id == null);}
}
You need to add a converter or a proper editor. I prefer the first one. Refer to section 6.5. on this page for the details.
Your converter would have to get the Entity with the given name from the database and return it. The code would be something like this:
class StringToGender implements Converter<String, Gender> {
#Autowired
private GenderRepository repository;
public Gender convert(String name) {
return repository.getGenderByName(name);
}
}
And in your application context xml (if you use xml):
<bean id="conversionService" class="org.springframework.format.support.FormattingConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="org.example.StringToGender"/>
</set>
</property>