could not initialize proxy - no Session REST запрос на Update

169
07 марта 2019, 19:30

Суть проблеми в том что у меня есть две модели, при одной модели Edit работаеш хорошо но когда добавил вторую модель с таким же функционалом то получаю

org.apache.jasper.JasperException: An exception occurred processing JSP page [/WEB-INF/pages/authors.jsp] at line [88]
85: 
86: <form:form action="${addAction}" commandName="author">
87:     <table>
88:         <c:if test="${!empty author.name}">
89:             <tr>
90:                 <td>
91:                     <form:label path="id">

Stacktrace:

org.apache.jasper.servlet.JspServletWrapper.handleJspException(JspServletWrapper.java:584)
Root Cause
javax.el.ELException: Error reading [name] on type [net.proselyte.bookmanager.model.Author_$$_jvst283_0]
Root Cause
org.hibernate.LazyInitializationException: could not initialize proxy - no Session

модуль

@Entity
@Table(name = "Author")
public class Author {
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private int id;
    @Column(name = "name")
    private String name;
    @Column(name = "gender")
    private String gender;
    @DateTimeFormat(pattern = "yyyy-MM-dd")
    @Column(name = "born")
    @Temporal(TemporalType.DATE)
    private Date born;
get set

DAO со всеми CRUD методамы

@Repository
public class AuthorDaoImpl implements AuthorDao {
    private SessionFactory sessionFactory;
    public void setSessionFactory(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    @Override
    public void addAuthor(Author author) {
        Session session = this.sessionFactory.getCurrentSession();
        session.persist(author);
    }
    @Override
    public void updateAuthor(Author author) {
        Session session = this.sessionFactory.getCurrentSession();
        session.update(author);
    }
    @Override
    public void removeAuthor(int id) {
        Session session = this.sessionFactory.getCurrentSession();
        Author author = (Author) session.load(Author.class, new Integer(id));
        if(author!=null){
            session.delete(author);
        }
    }
    @Override
    public Author getAuthorById(int id) {
        Session session =this.sessionFactory.getCurrentSession();
        Author author = (Author) session.load(Author.class, new Integer(id));
        return author;
    }
    @Override
    public List<Author> listAuthors() {
        Session session = this.sessionFactory.getCurrentSession();
        List<Author> authorList = session.createQuery("from Author").list();
        return authorList;
    }
}

@RequestMapping(value = "authors", method = RequestMethod.GET)
    public String listAuthors(Model model){
        model.addAttribute("author", new Author());
        model.addAttribute("listAuthors", this.authorService.listAuthors());
        return "authors";
    }
    @RequestMapping(value = "/authors/add", method = RequestMethod.POST)
    public String addBook(@ModelAttribute("author") Author author){
        if(author.getId() == 0){
            this.authorService.addAuthor(author);
        }else {
            this.authorService.updateAuthor(author);
        }
        return "redirect:/authors";
    }    
    @RequestMapping("editA/{id}")
    public String editAuthor(@PathVariable("id") int id, Model model){
        model.addAttribute("author", this.authorService.getAuthorById(id));
        model.addAttribute("listAuthors", this.authorService.listAuthors());
        return "authors";
    }

authors.jsp

<h1>Book List</h1>
<c:if test="${!empty listAuthors}">
    <table class="tg">
        <tr>
            <th width="80">ID</th>
            <th width="120">name</th>
            <th width="120">gender</th>
            <th width="120">born</th>
            <th width="60">Edit</th>
            <th width="60">Delete</th>
        </tr>
        <c:forEach items="${listAuthors}" var="author">
            <tr>
                <td>${author.id}</td>
                <td>${author.name}</td>
                <td>${author.gender}</td>
                <td>${author.born}</td>
                <td><a href="<c:url value='/editA/${author.id}'/>">Edit</a></td>
                <td><a href="<c:url value='/removeA/${author.id}'/>">Delete</a></td>
            </tr>
        </c:forEach>
    </table>
</c:if>

<h1>Add a Book</h1>
<c:url var="addAction" value="/authors/add"/>
<form:form action="${addAction}" commandName="author">
    <table>
        <c:if test="${!empty author.name}">
            <tr>
                <td>
                    <form:label path="id">
                        <spring:message text="ID"/>
                    </form:label>
                </td>
                <td>
                    <form:input path="id" readonly="true" size="8" disabled="true"/>
                    <form:hidden path="id"/>
                </td>
            </tr>
        </c:if>
        <tr>
            <td>
                <form:label path="name">
                    <spring:message text="name"/>
                </form:label>
            </td>
            <td>
                <form:input path="name"/>
            </td>
        </tr>
        <tr>
            <td>
                <form:label path="gender">
                    <spring:message text="gender"/>
                </form:label>
            </td>
            <td>
                <form:input path="gender"/>
            </td>
        </tr>
        <tr>
            <td>
                <form:label path="born">
                    <spring:message text="born"/>
                </form:label>
            </td>
            <td>
                <form:input path="born"/>
            </td>
        </tr>

            <td colspan="2">
                <c:if test="${!empty author.name}">
                    <input type="submit"
                           value="<spring:message text="Edit AAA"/>"/>
                </c:if>
                <c:if test="${empty author.name}">
                    <input type="submit"
                           value="<spring:message text="Add AAA"/>"/>
                </c:if>
            </td>
        </tr>
    </table>
</form:form>
</body>
</html>
Answer 1

Отдавать Entity не очень правильно.

Поэтому возникают такие ошибки. Используйте DTO когда отдаете Entity в jsp, замапте (Model Mapper) эту Entity в DTO и используйте.

Вся соль в том что в вашем Entity есть поле которое не загружены, а из-за того что этот класс обернут в прокси хабера. Вызывается метод get для поля и хибер пытается ее загрузить. Но эта операция вне транзакции и посему вылазит ошибка.

Пример DTO:

public class AuthorDTO {
    private int id;
    private String name;
    private String gender;
    private Date born;
    // get, set
}
READ ALSO
Как лучше сделать смену разметок на одном экране?

Как лучше сделать смену разметок на одном экране?

На основном экране есть "шапка" с навигацией, которая будет одинаковой (headxml)

125
Как узнать id view в AdapterView.OnItemClickListener

Как узнать id view в AdapterView.OnItemClickListener

У меня есть несколько AutoCompleteTextViewИ класс в котором они находятся реализует интерфейс AdapterView

123
Проблема при чтении из XML файла. Java, Sax parser

Проблема при чтении из XML файла. Java, Sax parser

У меня есть файл в 175 мб, и где-то в середине все ломается ( то есть до этого понятное дело нормально проходит)

151
Получение всех похожих view. Android

Получение всех похожих view. Android

Дано приложение где есть много одинаковых view и button,

157