Creation of dependend select - java

I created a jsp that will include two seletcts and one depends on the other.
In the first are city names:
<div class="container p-5">
<form action="/addFlat" method="post">
<div class="form-group">
<label for="exampleInputEmail1">City</label>
<select class="custom-select mr-sm-2" id="inlineFormCustomSelect">
<c:forEach items="${cities}" var="cities">
<option value="${cities.id}">${cities.name}</option>
</c:forEach>
</select>
</div>
I want the second to display street names that depend on the first.
I used hibernate to create tables.
City:
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#Column(name = "name")
private String name;
Street:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private long id;
#Column(name = "name")
private String name;
#ManyToOne
#JoinColumn(name = "city_id")
private City city;

Related

How do I convert string into Java Class in Spring?

I'm creating a new java entity with html post form,but I don't understand how to convert system id to a class System (that I pass with model.addAttribute("System",id); in controller).
Release
#Table(name = "treleas")
public class Release {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "release_id")
Integer releaseId;
#Column(name = "release_name", nullable = false)
private String releaseName;
#Column(name = "create_date", nullable = false)
private LocalDateTime releaseDate = LocalDateTime.now();
#ManyToOne
#JoinColumn(name = "system_id")
private System system;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name="release_id")
private List<Req> requirements;
}
System
#Entity
#Table(name = "tsystem")
public class System {
#Id
#Column(name = "system_id")
#GeneratedValue(strategy = GenerationType.IDENTITY)
Integer systemId;
#Column(name = "system_name", nullable = false)
private String systemName;
#OneToMany(fetch = FetchType.LAZY)
#JoinColumn(name="system_id")
private List<Release> releases;
}
Html new release
<!DOCTYPE html>
<html lang="en" xmlns:th="http://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Новый релиз</title>
</head>
<body>
<form th:method="POST" th:action="#{|/systems/${System}/releases|}"
th:object="${release}">
<label for="releaseName" >Введите название релиза: </label>
<input type="text" th:field="*{releaseName}" id="releaseName"/>
<div style="color:#f80d0d" th:if="${#fields.hasErrors('releaseName')}" th:errors="*{releaseName}"
>Name error</div>
<input type="hidden" th:field="*{system}" th:value="|${System}|"/>
<br/>
<input type="submit" value="Create!"/>
</form>
</body>
</html>
Exception
Caused by: org.postgresql.util.PSQLException: ОШИБКА: значение NULL в столбце "system_id" отношения "treleas" нарушает ограничение NOT NULL
Подробности: Ошибочная строка содержит (5, ReleaseName, 2022-05-15, null).
which means that it cannot insert release with a null system id

Invalid property 'projection' of bean class

Hi I need a little help with my code. I tried solutions online but I couldn't fix my bug. I working in java and spring with mysql and tymeleaf. My error is short:
Invalid property 'projection' of bean class [com.bakulic.CinemaTicketShop.model.dto.requests.CreateOrUpdateProjectionDTO]: Bean property 'projection' is not readable or has an invalid getter method: Does the return type of the getter match the parameter type of the setter?
And I found that my problem is in the html file createProjectionForm whitch I will put below as well as the entities and all that is needed. My projection entity has a relation to Hall and Movie and I'm not sure how to get attributes of Movie and Hall in my html. For the fiel I tried to put ${projection.hall.name} and ${projection.movie.movieName}. Zou will find it in the code.
Thank you in advance.
#Data
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
#Entity
#Table(name = "projections")
public class Projection {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int projectionId;
#Column(name = "date")
private String date;
#Column(name = "startTime")
private String startTime;
#ManyToOne
#JoinColumn(name = "idHall")
private Hall hall;
#ManyToOne
#JoinColumn(name = "idMovie")
private Movie movie;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "projection", cascade = CascadeType.ALL)
private List<Seat> seatList;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "projection", cascade = CascadeType.ALL)
private List<Ticket> ticketList;
}
#Entity
#Table(name = "halls")
#Data
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class Hall {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int hallId;
#Column(name = "name")
private String name;
#Column(name = "numberofseats")
private Integer numberOfSeats;
#Column(name = "description")
private String description;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "hall", cascade = CascadeType.ALL)
private List<Projection> projectionList;
}
#Entity
#Table(name = "movies")
#Data
#Getter
#Setter
#NoArgsConstructor
#AllArgsConstructor
public class Movie {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "id")
private int movieId;
#Column(name = "name")
private String name;
#Column(name = "description")
private String description;
#Column (name = "length")
private String length;
#Column(name = "picture")
private String picture;
#OneToMany(fetch = FetchType.LAZY, mappedBy = "movie", cascade = CascadeType.ALL)
private List<Projection> projectionList;
}
#Data
public class ProjectionDTO implements Serializable {
private int id;
private String date;
private String startTime;
private List<Seat> seatList;
private List<Ticket> ticketList;
private Hall hall;
private Movie movie;
public ProjectionDTO(Projection projection){
if(projection != null){
this.id = projection.getProjectionId();
this.date = projection.getDate();
this.startTime = projection.getStartTime();
this.seatList = projection.getSeatList();
this.ticketList = projection.getTicketList();
this.hall = projection.getHall();
this.movie = projection.getMovie();
}
}
}
#Data
#NoArgsConstructor
#AllArgsConstructor
#Builder
public class CreateOrUpdateProjectionDTO implements Serializable {
private String date;
private String startTime;
private List<Seat> seatList;
//aditional info
private String name;
private String movieName;
}
/** create projection*/
public Projection createProjection(CreateOrUpdateProjectionDTO createProjectionDTO){
if(createProjectionDTO == null){
throw new InvalidDataException("Projection cannot be null");
}
timeValidator.checkTime(createProjectionDTO.getStartTime());
dateValidator.checkDate(createProjectionDTO.getDate());
Projection proj = new Projection();
proj.setDate(createProjectionDTO.getDate());
proj.setStartTime(createProjectionDTO.getStartTime());
Hall hall = proj.getHall();
if(hall == null){
hall = new Hall();
}
hall.setName(createProjectionDTO.getName());
Integer numOfSeats = hall.getNumberOfSeats();
Movie movie = proj.getMovie();
if(movie == null){
movie = new Movie();
}
movie.setName(createProjectionDTO.getMovieName());
List<Seat> list = createProjectionDTO.getSeatList();
for(int i=1; i<=numOfSeats; i++ ){
Seat seat = new Seat();
seat.setSeatNumber(i);
seat.setStatus("empty");
list.add(seat);
}
Projection projCreated = projectionRepository.save(proj);
log.info(String.format("Projection %s has been created.", proj.getProjectionId()));
return projCreated;
} The function is similar for update.
<
<!DOCTYPE html>
<html lang="en" xmlns:th="http://thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Create theater</title>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
crossorigin="anonymous">
</head>
<body style="background-color:lightgrey;">
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<img src="../pictures/cinemalogo.png" th:src="#{pictures/cinemalogo.png}" class = "center"alt="logo" width="120" height="100"/>
<ul class="navbar-nav">
<li class="nav-item">
<h1>Our cinema!</h1>
</li>
</ul>
<ul class="navbar-nav">
<li class="nav-item">
<a class="nav-link" href="/logout">Logout</a>
</li>
</ul>
</nav>
</nav>
<br>
<br>
<div class="container">
<div class="row">
<div class="col-md-6 col-md-offset-3">
<h1>Add projection</h1><br>
<form th:action="#{/projection}" method="post" th:object="${projection}">
<div class="form-group">
<label class="control-label" for="date"> Date </label>
<input id="date" class="form-control" th:field="*{date}"
required autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="startTime"> Start time</label> <input
id="startTime" class="form-control" th:field="*{startTime}" required
autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="hallName"> Hall name </label> <input
id="hallName" class="form-control" th:field="*{projection.hall.name}" required
autofocus="autofocus" />
</div>
<div class="form-group">
<label class="control-label" for="movieName"> Movie name </label> <input
id="movieName" class="form-control" th:field="*{projection.movie.movieName}" required
autofocus="autofocus" />
</div>
<div class="form-group">
<button type="submit" class="btn btn-success">Submit</button>
</div>
</form>
</div>
</div>
</div>
</body>
</html>
Use th:field="*{hall.name}" instead of th:field="*{projection.hall.name}" and th:field="*{movie.movieName}" instead of th:field="*{projection.movie.movieName}"

Pass two objects with bidirectional One to One relationship into one Thymeleaf form

I'm working on a JPA project in which I have two models: TableDecor and Product Tag, which look like this:
#Entity(name="table_decor")
public class TableDecor {
#Id
#IdConstraint
private String id;
#Positive
#Column(nullable = false)
private int width;
#Positive
#Column(nullable = false)
private int height;
#NotNull
#Enumerated(EnumType.STRING)
#Column(nullable = false)
private Color color;
#NotNull
#Enumerated(EnumType.STRING)
#Column(nullable = false)
private Fabric fabric;
#ManyToMany
#JoinTable(
name = "seller",
joinColumns = #JoinColumn(name = "table_decor_id"),
inverseJoinColumns = #JoinColumn(name = "seller_id"))
private List<Seller> sellers;
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name="producer_id")
private Producer producer;
#OneToOne(cascade=CascadeType.ALL, fetch = FetchType.LAZY)
#JoinColumn(name = "product_tag_id", referencedColumnName = "id")
private ProductTag productTag;
// getters, setters
#Entity(name="product_tag")
#Table
public class ProductTag {
#Id
#GeneratedValue
private UUID id;
#NotNull
#Enumerated
#Column(nullable = false)
private ProductState productState;
#Column(nullable = false)
#NotNull
private float price;
#OneToOne(cascade=CascadeType.ALL, fetch = FetchType.EAGER)
#JoinColumn(name = "table_decor_id", referencedColumnName = "id")
private TableDecor tableDecor;
// getters, setters
As you can see they're connected with each other with bidirectional one to one relationship. Since one can't exist without another, how can I create a Thymeleaf add form that could create both objects at the same time? The controller function currently looks like this:
#GetMapping("/table-decor/add")
public String showAddForm(TableDecor decorToAdd, ProductTag productTag) {
return "table-decor-add";
}
#PostMapping("/table-decor/add-new")
public String addTableDecor(#Valid TableDecor decorToAdd, #Valid ProductTag productTag, BindingResult bindingResult, Model model){
if (bindingResult.hasErrors()) {
System.out.println("Error");
return "table-decor-add";
}
decorToAdd.setProductTag(productTag);
tableDecorService.addTableDecor(decorToAdd);
model.addAttribute("allTableDecor", tableDecorService.getAllTableDecor());
return "redirect:/table-decor";
and the form:
<form action="#" method="post" th:action="#{/table-decor/add-new}">
<div><input name="id" type="text" th:value="${tableDecor.id}"></div>
<span th:if="${#fields.hasErrors('tableDecor.id')}" th:errors="*{tableDecor.id}"></span>
<div><input name="width" type="text" th:value="${tableDecor.width}"></div>
<span th:if="${#fields.hasErrors('tableDecor.width')}" th:errors="*{tableDecor.width}"></span>
<div><input name="height" type="text" th:value="${tableDecor.height}"></div>
<span th:if="${#fields.hasErrors('tableDecor.height')}" th:errors="*{tableDecor.height}"></span>
<select name="color">
<option th:each="color : ${T(jee.labs.lab05.domain.Color).values()}"
th:text="${color}"
th:value="${tableDecor.color}">
</option>
</select>
<select name="fabric">
<option th:each="fabric : ${T(jee.labs.lab05.domain.Fabric).values()}"
th:text="${fabric}"
th:value="${tableDecor.fabric}">
</option>
</select>
<select name="productState">
<option th:each="productState : ${T(jee.labs.lab05.domain.ProductState).values()}"
th:text="${productState}"
th:value="${productTag.productState}">
</option>
</select>
<div><input name="price" type="text" th:value="${productTag.price}"></div>
<span th:if="${#fields.hasErrors('productTag.price')}" th:errors="*{productTag.price}"></span>
<div><input type="submit" th:value="Submit"></div>
</form>

Hibernate Update not working...using Spring framework

POJO:
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Basic(optional = false)
#Column(name = "id")
private Integer id;
#Basic(optional = false)
#Column(name = "name")
private String name;
#Generated(GenerationTime.INSERT)
#Basic(optional = false)
#Column(name = "created_at")
#Temporal(TemporalType.TIMESTAMP)
private Date createdAt;
#Generated(GenerationTime.ALWAYS)
#Basic(optional = false)
#Column(name = "updated_at")
#Temporal(TemporalType.TIMESTAMP)
private Date updatedAt;
Controller:
#Controller
#RequestMapping(value = "/")
public class HomeController {
#Autowired
private NameDao nDao;
#RequestMapping(value="/update/{id}", method=RequestMethod.GET)
public String getUpdate(#PathVariable int id, Model model){
Stamp st = (Stamp) nDao.getById(id);
model.addAttribute("s", st);
return "update";
}
#RequestMapping(value="/update/{id}", method=RequestMethod.POST)
public String postUpdate(#ModelAttribute Stamp s){
nDao.updateName(s);
return "redirect:/";
}
Update.jsp:
<h1>Update Here...</h1>
<form method = "post">
<div>
<label>Name: </label><input type="text" value="${s.name}" name="name">
</div>
<input type="submit" value="Submit">
</form>
My only concern is using the createdAt and updatedAt for each entry. On using createdAt and updatedAt dateTime, the problem of updating arose. Update now working. Any solution to use dateTime for createdAt and updatedAt working with upadate operation. Insert option works fine here.
Use #CreationTimestamp and #UpdateTimestamp instead of manually setting those values

Using spring-form tags to insert/update entity with non-primitive attributes

In my spring application, the forms for insert/update a entity in the database have a structure similar to this:
<jsp:include page="../../common/cadastrar.jsp">
<jsp:param name="entity" value="Usuario"/>
<jsp:param name="arguments" value="login"/>
<jsp:param name="arguments" value="senha"/>
<jsp:param name="arguments" value="first_name"/>
<jsp:param name="arguments" value="last_name"/>
<jsp:param name="arguments" value="email"/>
</jsp:include>
which redirect to this shared jsp page (common to all the views):
<c:url value="${param.entity}/cadastra" var="cadastra"/>
<form:form class="form" role="form" method="post" action="${cadastra}">
<table>
<c:forEach var="item" items="${paramValues.arguments}">
<c:choose>
<c:when test="${item == 'senha'}">
<tr>
<td><form:label path="${item}">${item}</form:label></td>
<td><form:input path="${item}" type="password"/></td>
</tr>
</c:when>
<c:otherwise>
<tr>
<td><form:label path="${item}">${item}</form:label></td>
<td><form:input path="${item}"/></td>
</tr>
</c:otherwise>
</c:choose>
</c:forEach>
<tr>
<td colspan="2">
<button type="submit" class="btn btn-lg btn-primary">Cadastrar</button>
</td>
</tr>
</table>
</form:form>
When my entity class have only primitive attributes (Integer, String, etc), this code works fine. But I can't figure out how to do the same for classes like that:
#Entity
#Table(name="cliente")
public class Cliente extends Entidade {
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#OneToOne
#JoinColumn(name="fk_usuario")
private Usuario usuario;
#Column(name="documento")
private String documento;
#Column(name="cpf")
private String cpf;
#Column(name="cnpj")
private String cnpj;
#ManyToMany
#JoinTable(name="endereco_entrega", joinColumns={#JoinColumn(name="fk_cliente")}, inverseJoinColumns={#JoinColumn(name="fk_endereco")})
#LazyCollection(LazyCollectionOption.FALSE)
private List<Endereco> endereco;
#ManyToMany
#JoinTable(name="pedido_cliente", joinColumns={#JoinColumn(name="fk_cliente")}, inverseJoinColumns={#JoinColumn(name="fk_pedido")})
#LazyCollection(LazyCollectionOption.FALSE)
private List<Pedido> pedido;
}
where some of the attributes are other entities. Anyone can point me a direction to do this?
UPDATE 1
Usuario.java
#Entity
#Table(name="usuario")
public class Usuario extends Entidade {
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name = "login")
private String login;
#Column(name = "senha")
private String senha;
#Column(name="first_name")
private String first_name;
#Column(name="last_name")
private String last_name;
#Column(name="email")
private String email;
#ManyToMany
#JoinTable(name="role_members", joinColumns={#JoinColumn(name="fk_user")}, inverseJoinColumns={#JoinColumn(name="fk_role")})
#LazyCollection(LazyCollectionOption.FALSE)
private List<Role> Autorizacao = new ArrayList<Role>();
}
Endereco.java
#Entity
#Table(name="endereco")
public class Endereco {
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#Column(name="logadouro")
private String logradouro;
#Column(name="numero")
private String numero;
#Column(name="complemento")
private String complemento;
#Column(name="bairro")
private String bairro;
#Column(name="cidade")
private String cidade;
#Column(name="estado")
private String estado;
#Column(name="cep")
private String cep;
}
Pedido.java
#Entity
#Table(name="pedido")
public class Pedido {
#Id
#Column(name = "id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
#ManyToMany
#JoinTable(name="produtos_do_pedido", joinColumns={#JoinColumn(name="fk_pedido")}, inverseJoinColumns={#JoinColumn(name="fk_produto")})
#LazyCollection(LazyCollectionOption.FALSE)
private List<Produto> produto;
#ManyToMany
#JoinTable(name="cobranca_do_pedido", joinColumns={#JoinColumn(name="fk_pedido")}, inverseJoinColumns={#JoinColumn(name="fk_cobranca")})
#LazyCollection(LazyCollectionOption.FALSE)
private List<Cobranca> cobranca;
}

Categories

Resources