Spring could not prepare statement because of a not found column - spring

I'm working with jhipster, I got the following jdl format:
I've made some modification on the domains that looks like:
#Entity
#Table(name = "client_account")
#Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class ClientAccount implements Serializable {
private static final long serialVersionUID = 1L;
#Id
private Long id;
#NotNull
#Column(name = "first_name", nullable = false)
private String firstName;
#NotNull
#Column(name = "last_name", nullable = false)
private String lastName;
#NotNull
#Column(name = "phone", nullable = false)
private String phone;
#Column(name = "identity")
private String identity;
#Column(name = "referal")
private String referal;
#Column(name = "refered_by")
private String referedBy;
#OneToOne
#MapsId
private User user;
#OneToMany(mappedBy = "clientAccount")
private Set<Reputation> reputations = new HashSet<>();
#OneToMany(mappedBy = "clientAccount")
private Set<Trip> trips = new HashSet<>();
and the reputations domain:
#Entity
#Table(name = "reputation")
public class Reputation implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Column(name = "rate", nullable = false)
private Integer rate;
#Column(name = "comment")
private String comment;
#ManyToOne
#JsonIgnoreProperties("reputations")
private TransporterAccount transporterAccount;
#ManyToOne
#JsonIgnoreProperties("reputations")
private ClientAccount clientAccount;
The user domain:
#Entity
#Table(name = "jhi_user")
public class User extends AbstractAuditingEntity implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
#NotNull
#Pattern(regexp = Constants.LOGIN_REGEX)
#Size(min = 1, max = 50)
#Column(length = 50, unique = true, nullable = false)
private String login;
#JsonIgnore
#NotNull
#Size(min = 60, max = 60)
#Column(name = "password_hash", length = 60, nullable = false)
private String password;
#Size(max = 50)
#Column(name = "first_name", length = 50)
private String firstName;
#Size(max = 50)
#Column(name = "last_name", length = 50)
private String lastName;
#Email
#Size(min = 5, max = 254)
#Column(length = 254, unique = true)
private String email;
#NotNull
#Column(nullable = false)
private boolean activated = false;
#Size(min = 2, max = 10)
#Column(name = "lang_key", length = 10)
private String langKey;
#Size(max = 256)
#Column(name = "image_url", length = 256)
private String imageUrl;
#Size(max = 20)
#Column(name = "activation_key", length = 20)
#JsonIgnore
private String activationKey;
#Size(max = 20)
#Column(name = "reset_key", length = 20)
#JsonIgnore
private String resetKey;
#Column(name = "reset_date")
private Instant resetDate = null;
#JsonIgnore
#ManyToMany
#JoinTable(
name = "jhi_user_authority",
joinColumns = {#JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {#JoinColumn(name = "authority_name", referencedColumnName = "name")})
#BatchSize(size = 20)
private Set<Authority> authorities = new HashSet<>();
The Transporter liquibase is mapped as follow:
<changeSet id="20200218210800-1" author="jhipster">
<createTable tableName="client_account">
<column name="user_id" type="bigint">
<constraints primaryKey="true" nullable="false"/>
</column>
<column name="first_name" type="varchar(255)">
<constraints nullable="false" />
</column>
<column name="last_name" type="varchar(255)">
<constraints nullable="false" />
</column>
<column name="phone" type="varchar(255)">
<constraints nullable="false" />
</column>
<column name="identity" type="varchar(255)">
<constraints nullable="true" />
</column>
<column name="referal" type="varchar(255)">
<constraints nullable="true" />
</column>
<column name="refered_by" type="varchar(255)">
<constraints nullable="true" />
</column>
<!-- jhipster-needle-liquibase-add-column - JHipster will add columns here, do not remove-->
</createTable>
</changeSet>
<changeSet id="20200218210800-2" author="jhipster">
<addForeignKeyConstraint baseColumnNames="user_id"
baseTableName="client_account"
constraintName="fk_client_account_user_id"
referencedColumnNames="id"
referencedTableName="jhi_user"/>
</changeSet>
and the reputations liquibase:
<changeSet id="20200218210700-1-data" author="jhipster" context="faker">
<loadData
file="config/liquibase/fake-data/reputation.csv"
separator=";"
tableName="reputation">
<column name="id" type="numeric"/>
<column name="rate" type="numeric"/>
<column name="comment" type="string"/>
<!-- jhipster-needle-liquibase-add-loadcolumn - JHipster (and/or extensions) can add load columns here, do not remove-->
</loadData>
</changeSet>
<changeSet id="20200218210700-2" author="jhipster">
<addForeignKeyConstraint baseColumnNames="transporter_account_id"
baseTableName="reputation"
constraintName="fk_reputation_transporter_account_id"
referencedColumnNames="user_id"
referencedTableName="transporter_account"/>
<addForeignKeyConstraint baseColumnNames="client_account_id"
baseTableName="reputation"
constraintName="fk_reputation_client_account_id"
referencedColumnNames="user_id"
referencedTableName="client_account"/>
</changeSet>
Still I'm getting the following stacktrace error:
select reputation0_.id as id1_14_, reputation0_.client_account_user_id
as client_a4_14_, reputation0_.comment as comment2_14_,
reputation0_.rate as rate3_14_,
reputation0_.transporter_account_user_id as transpor5_14_ from
reputation reputation0_ order by reputation0_.id asc limit ?
[42122-200] 2020-02-20 09:48:03.515 ERROR 23616 --- [ XNIO-1 task-7]
c.a.dropme.aop.logging.LoggingAspect : Exception in
com.abdrid.dropme.service.ReputationQueryService.findByCriteria() with
cause = 'org.hibernate.exception.SQLGrammarException: could not
prepare statement' and exception = 'could not prepare statement; SQL
[select reputation0_.id as id1_14_,
reputation0_.client_account_user_id as client_a4_14_,
reputation0_.comment as comment2_14_, reputation0_.rate as rate3_14_,
reputation0_.transporter_account_user_id as transpor5_14_ from
reputation reputation0_ order by reputation0_.id asc limit ?]; nested
exception is org.hibernate.exception.SQLGrammarException: could not
prepare statement'

I got a similar issue ... I added a new Field in an Entity known as title (String) and jhipster entity sub-generator worked well enough ... got no issues
code got compiled and portal was also working - but when I tried listing the entity page - the ajax call gave 500 Http Status - with internal server as "prepared statement could not be created" ...
I did
./mvnw clean integration-test
and then ran the ./mvnw normally again. All the cached code was flushed and portal started working back.

The table name you used, User, is a reserved keyword for H2 databases ?
First try to surround table name of User with double quotes. If it does not work, rename your table with a name like Employee.
There is a list of keywords that can't be used as identifiers (table names, column names and so on), unless they are quoted (surrounded with double quotes).
http://www.h2database.com/html/advanced.html#keywords

Related

Spring specification query for one to many join and sum of field is grater then given value

I am creating filter using joining this three entity seeker_job_application,seeker_profile and seeker_experience. where I want achieve result as below query.
In filter I want to find out seeker_profile whose total_moth of experience should be grater then or equal to given value i.e 20, one seeker_profile has multiple experience so I need to group by profile and sum of their experience and then compare with given value. is it possible to do this using spring specification?
How to check that seeker total month of experience is grater then or equal to given value?
Relation between table is
seeker_job_application 1<-->1 seeker_profile 1<---->* seeker_experience
Want to achieve query like this
select r.sja_id,r.sp_id,r.name,r.company_name,r.total_month from (
select sja.id as sja_id , sp.id as sp_id , sp.`name`,se.company_name,sum(se.total_month) as total_month
from seeker_job_application sja
INNER JOIN seeker_profile sp on sp.id = sja.seeker_id
INNER JOIN seeker_experience se on se.seeker_id = sp.id
where job_id =1 group by sp.id ) as r where r.total_month > 20;
#Entity
#Table(name = "seeker_job_application")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SeekerJobApplication implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#NotNull
#Column(name = "seeker_id", nullable = false)
private Long seekerId;
#NotNull
#Column(name = "job_id", nullable = false)
private Long jobId;
#Column(name = "apply_date")
private Instant applyDate;
#Column(name = "profile_viewed")
private Boolean profileViewed;
#Column(name = "on_hold")
private Boolean onHold;
#Column(name = "interview_schedule")
private Boolean interviewSchedule;
#Column(name = "rejected")
private Boolean rejected;
#Column(name = "selected")
private Boolean selected;
#Column(name = "prefered_location_id")
private Long preferedLocationId;
#Column(name = "work_preference")
private String workPreference;
#Column(name = "resume_file_path")
private String resumeFilePath;
#Column(name = "status")
private String status;
#ManyToOne
#JoinColumn(name="seeker_id",referencedColumnName = "id", insertable = false, updatable = false)
private SeekerProfile seekerProfile;
#Data
#Entity
#Table(name = "seeker_profile")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SeekerProfile implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "id")
private Long id;
#Column(name = "name", nullable = false)
private String name;
#Column(name = "mobile_number", nullable = false)
private String mobileNumber;
#Column(name = "password")
private String password;
#Column(name = "email", nullable = false)
private String email;
#Column(name = "house_number")
private String houseNumber;
#Column(name = "address_line_1")
private String addressLine1;
#Column(name = "address_line_2")
private String addressLine2;
#Column(name = "city")
private String city;
#Column(name = "postcode")
private String postcode;
#Column(name = "state")
private String state;
#Column(name = "country")
private String country;
#Column(name = "website")
private String website;
#Column(name = "linkedin")
private String linkedin;
#Column(name = "facebook")
private String facebook;
#Column(name = "gender")
private String gender;
#Column(name = "dob")
private String dob;
#Column(name = "resume")
private String resume;
#Column(name = "wfh")
private String wfh;
#Column(name = "profile_completed")
private String profileCompleted;
#OneToOne
#JoinColumn(unique = true)
private Location preferedLocation;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "seeker_skill", joinColumns = { #JoinColumn(name = "seeker_id") }, inverseJoinColumns = { #JoinColumn(name = "skill_id") })
private Set<Skill> skills;
#OneToMany(fetch = FetchType.EAGER)
#JoinColumn(name="seeker_id",referencedColumnName = "id", insertable = false, updatable = false)
private Set<SeekerExperience> seekerExperiences;
#OneToMany
#JoinColumn(name="seeker_id",referencedColumnName = "id", insertable = false, updatable = false)
private Set<SeekerEducation> seekerEducation;
#Entity
#Table(name = "seeker_experience")
#Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
public class SeekerExperience implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
#NotNull
#Column(name = "seeker_id", nullable = false)
private Long seekerId;
#NotNull
#Column(name = "job_title", nullable = false)
private String jobTitle;
#NotNull
#Column(name = "company_name", nullable = false)
private String companyName;
#NotNull
#Column(name = "start_date", nullable = false)
private String startDate;
#NotNull
#Column(name = "end_date", nullable = false)
private String endDate;
#Column(name = "total_month")
private Integer totalMonth;
#Column(name = "location")
private String location;
#Column(name = "role_description")
private String roleDescription;
Specification<SeekerJobApplication> specification = Specification.where(null);
specification = specification.and((root, query, cb) -> {
Join<SeekerJobApplication, SeekerProfile> seekerProfile=root.join(SeekerJobApplication_.seekerProfile);
Join<SeekerProfile, SeekerExperience> seekerExperience = seekerProfile.join(SeekerProfile_.seekerExperiences);
query.having(cb.greaterThanOrEqualTo(cb.sum(seekerExperience.get(SeekerExperience_.totalMonth)), criteria.getTotalExperience().getEquals()));
query.getRestriction();
});
This will give me result as below query
select sja.* from seeker_job_application sja
INNER JOIN seeker_profile sp on sja.seeker_id = sp.id
INNER JOIN seeker_experience se on se.seeker_id = sp.id
where sja.job_id = 1
GROUP BY sp.id
having sum(se.total_month) > 20

thymeleaf mapping of object that has an inner object within a form

i have 2 objects one is persisting (product) the other is an an embeddable address (storeWhereLocated), this object persists within product.
i am trying to create a form to persist the product using thymeleaf.
here is the Product entity im trying to persist
public class Product {
#Embedded
#AttributeOverrides(value = {
#AttributeOverride(name = "addressLine1", column = #Column(name = "address")),
#AttributeOverride(name = "addressLine2", column = #Column(name = "unit")),
#AttributeOverride(name = "city", column = #Column(name = "city")),
#AttributeOverride(name = "state", column = #Column(name = "state")),
#AttributeOverride(name = "zipCode", column = #Column(name = "zip_code"))
})
private Address storeWhereLocated;
}
this is the Address object no persisting needed here only within product entity
#Embeddable
public class Address {
#NotNull
#Size(min=2, max = 100)
private String addressLine1;
#NotNull
#Size(max = 50)
private String addressLine2;
#NotNull
#Size(min=2, max = 50)
private String city;
#NotNull
#Size(min= 2, max = 25)
private String state;
#NotNull
#Size(min=1, max = 6)
private String zipCode;
here is the form
<form th:action="#{/product/add}" method="post" th:object="${product}"
enctype="multipart/form-data">
<input th:field="*{storeWhereLocated.addressLine1}"/>
<input th:field="*{storeWhereLocated.addressLine2}"/>
<input th:field="*{storeWhereLocated.city}"/>
<input th:field="*{storeWhereLocated.state}"/>
<input th:field="*{storeWhereLocated.zipCode}"/>
</form>
my question is will this work the way i have it or not. i am trying to read up on it but could not come across anything.

How to prevent user from injecting field into form backing bean?

An user upload his comment via this form.
Thymeleaf
<form th:action="#{/comment}" th:id="form" method="post">
<input type="hidden" th:name="productId.id" th:value="${product.id}">
<textarea th:field="${comment.message}" class="comment"
placeholder="Write comment here"></textarea>
<input type="submit" id="submit" value="comment">
</form>
Actual HTML
<form action="/comment" id="form" method="post" class="">
<input type="hidden" name="_csrf" value="f6b3f296-3284-4d2d-a2b2-0a9975f5e071">
<input type="hidden" name="productId.id" value="38">
<textarea class="comment" placeholder="Write comment here" id="message" name="message"></textarea>
<input type="submit" id="submit" value="comment">
</form>
However if user overwrites the actual HTML like this, the product's name will be changed to "ABCD"
<form action="/comment" id="form" method="post" class=""><input type="hidden" name="_csrf" value="f6b3f296-3284-4d2d-a2b2-0a9975f5e071">
<input type="hidden" name="productId" value="38">
<input type="hidden" name="productId.name" value="ABCD">
<textarea class="comment" placeholder="Write comment here" id="message" name="message"></textarea>
<input type="submit" id="submit" value="comment">
</form>
I think what happened here is Spring queried the productId and it became managed Entity, and when the user set the name to be "ABCD", it would be saved.
Here is my solution:
Basically just use #Validated with a bunch of groups and put constraint with appropriate groups (UploadCommentValidation in this case) on every single field, which works but seems really messy especially when it gets big.
Example with upload comment above:
Comment Entity: productId and message must be #Not Null, productId must be #Valid,other fields must be #Null
Product Entity: Id must be #NotNull, other fields must be #Null
Comment entity
public class Comment implements Comparable<Comment> {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Null(groups = {UploadCommentValidation.class})
#NotNull(groups = {DeleteCommentValidation.class, UpdateCommentValidation.class})
private Integer id;
#ManyToOne
#JoinColumn(name = "product_id", referencedColumnName = "id")
#JsonBackReference
#Valid
#NotNull(groups = {UploadCommentValidation.class})
#Null(groups = {DeleteCommentValidation.class, UpdateCommentValidation.class})
private Product productId;
#ManyToOne
#JoinColumn(name = "user_id", referencedColumnName = "id")
#JsonBackReference
#Null(groups = {UploadCommentValidation.class, DeleteCommentValidation.class, UpdateCommentValidation.class})
private User userId;
#Column(name = "message")
#NotBlank(message = "please write a comment", groups = {UploadCommentValidation.class, UpdateCommentValidation.class})
#Null(groups = {DeleteCommentValidation.class})
private String message;
#Column(name = "created_at", insertable = false, columnDefinition = "timestamp with time zone not null")
#Temporal(TemporalType.TIMESTAMP)
#Null(groups = {UploadCommentValidation.class, DeleteCommentValidation.class, UpdateCommentValidation.class})
private Calendar createdAt;
#Column(name = "updated_at", columnDefinition = "timestamp with time zone not null")
#Temporal(TemporalType.TIMESTAMP)
#Null(groups = {UploadCommentValidation.class, DeleteCommentValidation.class, UpdateCommentValidation.class})
private Calendar updatedAt;
#Override
public int compareTo(Comment o) {
return this.getId().compareTo(o.getId());
}
}
Product entity
public class Product implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#NotNull(message = "product id null", groups = {AddOrderValidation.class, UploadCommentValidation.class})
#Null(message = "bad request", groups = {ProductRegisterValidation.class})
private Integer id;
#NotBlank(message = "please fill in product name", groups = {ProductRegisterValidation.class})
#Length(max = 255, message = "too long", groups = {ProductRegisterValidation.class})
#Null(groups = {AddOrderValidation.class, UploadCommentValidation.class})
#Column(name = "name")
private String name;
#Column(name = "price")
#Positive(message = "the price must be non-negative", groups = {ProductRegisterValidation.class})
#NotNull(message = "please fill in price", groups = {ProductRegisterValidation.class})
#Null(groups = {AddOrderValidation.class, UploadCommentValidation.class})
private Integer price;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "category_id", referencedColumnName = "id")
#Valid
#NotNull(message = "please select category name", groups = {ProductRegisterValidation.class})
#Null(groups = {AddOrderValidation.class, UploadCommentValidation.class})
private Category categoryId;
#NotBlank(message = "please fill in description", groups = {ProductRegisterValidation.class})
#Length(max = 10000, message = "too long", groups = {ProductRegisterValidation.class})
#Null(groups = {AddOrderValidation.class, UploadCommentValidation.class})
#Column(name = "description")
private String description;
#OneToMany(mappedBy = "product", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#Null(groups = {ProductRegisterValidation.class, AddOrderValidation.class, UploadCommentValidation.class})
private List<ProductImage> productImages;
#OneToOne(mappedBy = "product", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#Null(groups = {ProductRegisterValidation.class, AddOrderValidation.class, UploadCommentValidation.class})
private Thumbnail thumbnail;
#OneToMany(mappedBy = "productId", fetch = FetchType.LAZY)
#JsonManagedReference
#Null(groups = {ProductRegisterValidation.class, AddOrderValidation.class, UploadCommentValidation.class})
private List<Comment> comments;
#OneToMany(mappedBy = "product", fetch = FetchType.LAZY)
#Null(groups = {ProductRegisterValidation.class, AddOrderValidation.class, UploadCommentValidation.class})
private List<Order> orders;
}
Any ideas how to do it the right way? This seems super messy!
UPDATE 1: This is my rest controller
#PostMapping("/comment")
public ResponseEntity<Map<String, String>> commentResponseEntity(#Validated({UploadCommentValidation.class}) Comment comment, BindingResult result) {
if (result.hasErrors()) {
result.getAllErrors().forEach(System.out::println);
return ResponseEntity.noContent().build();
}
User user = getUser();
comment.setUserId(user);
commentRepository.saveAndFlush(comment);
Map<String, String> response = new HashMap<>();
response.put("comment", comment.getMessage());
response.put("user", user.getName());
response.put("commentId", comment.getId().toString());
return ResponseEntity.ok().body(response);
}
You can do this by registering an #InitBinder method
You can do this at the individual controller level or by registering a #ControllerAdvice to be applied to all, or a subset of all, controllers.
#InitBinder()
public void initBinder(WebDataBinder binder) {
binder.setDisallowedFields(new String[] { "id", "version" });
}

SpringBoot: How to rollback creation of parent if child creation fails?

I have two models namely Company and User.
A Company can have many Users. I use Spring data jpa to interact with the database.
User Model :
#Entity
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(length = 50, unique = true)
#NotNull
#Size(min = 4, max = 50)
private String username;
#NotNull
#Size(min = 8)
private String password;
#Column(length = 50)
#NotNull
#Size(min = 4, max = 50)
private String firstName;
#Column(length = 50)
#NotNull
#Size(min = 4, max = 50)
private String lastName;
#Column(length = 50, unique = true)
#NotNull
#Size(min = 4, max = 50)
private String email;
private Boolean enabled = true;
#Temporal(TemporalType.TIMESTAMP)
#UpdateTimestamp
private Date lastPasswordReset;
#Column(nullable = false, updatable = false)
#Temporal(TemporalType.TIMESTAMP)
#CreatedDate
private Date createdAt = new Date();
#Column(nullable = false)
#Temporal(TemporalType.TIMESTAMP)
#UpdateTimestamp
#LastModifiedDate
private Date updatedAt = new Date();
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(
name = "user_authority",
joinColumns = {#JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {#JoinColumn(name = "authority_id", referencedColumnName = "id")})
private List<Authority> authorities;
#ManyToOne(optional = false, fetch = FetchType.LAZY, cascade = CascadeType.REMOVE)
#JsonBackReference
private Company company;
... Getter and Setters
}
Company Model
#Entity
public class Company {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#NotNull
#Size(min = 4, max = 100)
private String name;
#Size(max = 500)
private String description;
#OneToMany(mappedBy = "company", cascade = CascadeType.ALL)
#JsonManagedReference
private List<User> users = new ArrayList<>();
...Followed by Getter and Setters
}
So I use Spring Data JPA to save Company which takes care of creating a User as well.
So today if for some reason the creation of user fails due to some exception, the company record still exists.
So I need that if creation of User fails the Company shall not be created(rollback).
How can I achieve this.

Explication about Spring Converter with Spring MVC - I can't understand

I'd like someone could explication about converter in spring mvc.
My domain class:
#Entity
#Table(name = "TIME_SHEET")
public class TimeSheet implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "ID_TIME_SHEET")
private Long id;
#NotNull(message = "timesheet.cadastro.horainicio.obrigatorio")
#Temporal(TemporalType.TIME)
#Column(name = "INICIO", nullable = false)
private Date horaInicio;
#NotNull(message = "timesheet.cadastro.horafim.obrigatorio")
#Temporal(TemporalType.TIME)
#Column(name = "FIM", nullable = false)
private Date horaFim;
#Column(name = "LATITUDE", nullable = true)
private Double latitude;
#Column(name = "LONGITUDE", nullable = true)
private Double longitude;
#Size(max = 300,message = "timesheet.cadastro.observacao.acimaDoPermitido")
#Column(name = "OBSERVACAO", nullable = true)
private String observacao;
//#NotNull(message = "timesheet.cadastro.dia.obrigatorio")
#ManyToOne(cascade = javax.persistence.CascadeType.ALL)
#JoinColumn(name = "ID_DIAS")
private Dias dia;
//#NotNull(message = "timesheet.cadastro.usuario.obrigatorio")
#ManyToOne(cascade = javax.persistence.CascadeType.ALL)
#JoinColumn(name = "ID_USUARIO")
private Usuario usuario;
...
My class converter:
public class IdToUsuarioConverter implements Converter<String, Usuario> {
#Autowired
private IusuarioService usuarioService;
public Usuario convert(String id) {
return usuarioService.buscaPorId(Long.valueOf(id));
}
}
In my springmvc.xml:
<mvc:annotation-driven conversion-service="conversionService"/>
<bean id="conversionService"
class="org.springframework.context.support.ConversionServiceFactoryBean">
<property name="converters">
<set>
<bean class="br.com.infowhere.timeSheet.converter.IdToUsuarioConverter"/>
</set>
</property>
</bean>
I don't have problem, but my question is:
1-) When my converter will act ?
2-) My .jsp will post a form where I have one list similar:
<form:select path="user" items="${userList}" multiple="false" />
HTML:
<select id="user" name="user">
<option value="1">User 1</option>
<option value="2">User 2</option>
</select>
At what time my converter will work ?
I'm sorry but I'm trying to understand about converter.
thanks !!!
Your converter will convert id's to Usario objects in your controllers.
For example:
#Controller
public class MyController {
#RequestMapping("/showUsario")
public String showUsario(#RequestParam("id") Usario usario, Model model) {
model.addAttribute("usario", usario);
return "showUsario";
}
}
Then a request to /showUsario?id=123 will convert String "123" to Usario using the converter. If you didn't have a converter you would have to put String id (instead of Usario) in method parameters and manually convert the id to Usario. This way, Spring does it for you using your converter.

Resources