Skip to content
Advertisement

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>

Advertisement

Answer

Use th:field="*{hall.name}" instead of th:field="*{projection.hall.name}" and th:field="*{movie.movieName}" instead of th:field="*{projection.movie.movieName}"

User contributions licensed under: CC BY-SA
3 People found this is helpful
Advertisement