Удалить из таблицы в спящем отношении один к одному - PullRequest
0 голосов
/ 26 августа 2018

Я использую MySQL, Hibernate и Spring MVC в своем приложении CRUD. У меня есть две сущности в однонаправленных отношениях один-к-одному. Когда я удаляю пользователя, адрес остается в базе данных. Пользователь и адрес добавлены правильно. В чем дело? Я проверил все темы в стеке и не нашел причину этого сбоя ... Ниже приведен мой код Java и сценарии SQL.

User.java

@Table
@Entity(name = "User")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "first_name")
    private String firstName;
    @Column(name = "last_name")
    private String lastName;

    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "address_id")
    private Address address;

    public User() {

    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getFirstName() {
        return firstName;
    }

    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }

    public String getLastName() {
        return lastName;
    }

    public void setLastName(String lastName) {
        this.lastName = lastName;
    }

    public Address getAddress() {
        return address;
    }

    public void setAddress(Address address) {
        this.address = address;
    }

    @Override
    public String toString() {
        return "User [id=" + id + ", firstName=" + firstName + ", lastName=" + lastName + ", address=" + address + "]";
    }

}

Address.java

@Entity
@Table(name = "address")
public class Address {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "id")
    private int id;

    @Column(name = "street")
    private String street;
    @Column(name = "city")
    private String city;
    @Column(name = "zip_code")
    private String zipCode;


    public Address() {

    }

    public Address(String street, String city, String zipCode) {
        this.street = street;
        this.city = city;
        this.zipCode = zipCode;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getStreet() {
        return street;
    }

    public void setStreet(String street) {
        this.street = street;
    }

    public String getCity() {
        return city;
    }

    public void setCity(String city) {
        this.city = city;
    }

    public String getZipCode() {
        return zipCode;
    }

    public void setZipCode(String zipCode) {
        this.zipCode = zipCode;
    }

    @Override
    public String toString() {
        return "Address [id=" + id + ", street=" + street + ", city=" + city + ", zipCode=" + zipCode + "]";
    }

}

GenericService.java

public interface GenericService<T> {

    List<T> getAll();

    void save(T t);

    User getOne(int id);

    void delete(int id);
}

UserService.java

@Service
public class UserService implements GenericService<User> {

    @Autowired
    private UserDAO userDao;

    @Override
    @Transactional
    public List<User> getAll() {
        return userDao.getAll();
    }

    @Override
    @Transactional
    public void save(User user) {
        userDao.save(user);
    }

    @Override
    @Transactional
    public User getOne(int id) {
        return userDao.getOne(id);
    }

    @Override
    @Transactional
    public void delete(int id) {
        userDao.delete(id);
    }

}

AbstractDAO.java

public abstract class AbstractDAO<T> {

    @Autowired
    public SessionFactory sessionFactory;

    protected Class<T> entityClass;

    public AbstractDAO() {
        ParameterizedType pt = (ParameterizedType) getClass().getGenericSuperclass();
        entityClass = (Class<T>) pt.getActualTypeArguments()[0];
    }

    public T getOne(int id) {
        Session session = sessionFactory.getCurrentSession();
        T t = session.get(entityClass, id);
        return t;
    }

    public List<T> getAll() {
        Session session = sessionFactory.getCurrentSession();
        TypedQuery<T> query = session.createQuery("from " + entityClass.getSimpleName(), entityClass);
        List<T> t = query.getResultList();
        return t;
    }

    public T save(T t) {
        Session session = sessionFactory.getCurrentSession();
        session.saveOrUpdate(t);
        return t;
    }

    public void delete(int id) {
        Session session = sessionFactory.getCurrentSession();
        TypedQuery<T> query = session.createQuery("delete from " + entityClass.getSimpleName() + " where id=:id");
        query.setParameter("id", id);
        query.executeUpdate();
    }
}

UserDAO.java

@Repository
public class UserDAO  extends AbstractDAO<User>{

    @Autowired
    private SessionFactory sessionFactory;

    public List<User> getAll(){
        Session session = sessionFactory.getCurrentSession();
        TypedQuery<User> query = session.createQuery("from "+entityClass.getSimpleName(),entityClass);
        List<User> userList = query.getResultList();
        return userList;
    }

    public User save(User user) {
        Session currentSession = sessionFactory.getCurrentSession();
        currentSession.saveOrUpdate(user);
        return user;
    }


    public void delete(int id) {
        Session session = sessionFactory.getCurrentSession();
        TypedQuery<User> query = session.createQuery("delete from "+ entityClass.getSimpleName()+" where id=:id");
        query.setParameter("id",id);
        query.executeUpdate();
    }
}

UserController.java

@Controller
@RequestMapping("/user")
public class UserController {

    @Autowired
    private UserService userService;

    @InitBinder
    public void initBinder(WebDataBinder dataBinder) {
        StringTrimmerEditor stringTrimmerEdition = new StringTrimmerEditor(true);
        dataBinder.registerCustomEditor(String.class, stringTrimmerEdition);
    }

    @GetMapping("/list")
    public String userList(Model theModel) {
        List<User> theUsers = userService.getAll();
        theModel.addAttribute("users", theUsers);
        return "list-users";
    }

    @GetMapping("/showFormForAdd")
    public String showFormForAdd(Model theModel) {
        User theUser = new User();
        theModel.addAttribute("user", theUser);
        return "user-form";
    }

    @PostMapping("/saveUser")
    public String saveUser(@ModelAttribute("user") User theUser, BindingResult bindingResult) {
        userService.save(theUser);
        return "redirect:/user/list";
    }

    @GetMapping("/showFormForUpdate")
    public String showFormForUpdate(@RequestParam("userId") int theId, Model theModel) {
        User user = userService.getOne(theId);
        theModel.addAttribute("user", user);
        return "user-form";
    }

    @GetMapping("/delete")
    public String deleteUser(@RequestParam("userId") int theId) {
        userService.delete(theId);
        return "redirect:/user/list";
    }

}

список-form.jsp

<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core"%>
<%@ taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>

<link rel="stylesheet"
    href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
    integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
    crossorigin="anonymous">
<script
    src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
    integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
    crossorigin="anonymous"></script>
<title>SimpleCRUD</title>
</head>
<body>

    <nav class="navbar navbar-dark bg-primary" style="color: white">
        <h3>
            <i>SimpleCRUD</i>
            <h3>
    </nav>

    <div class="container-fluid text-center">
        <div class="row">
            <div class="col-md-12">
                <br>
                <h3>
                    <i>Lista użytkowników</i>
                </h3>
                <br>
                <table class="table table-sm text-center">
                    <thead>
                        <tr>
                            <th>Imię</th>
                            <th>Nazwisko</th>
                            <th>Ulica</th>
                            <th>Miasto</th>
                            <th>Kod pocztowy</th>
                            <th></th>
                        </tr>
                    </thead>
                    <tbody>
                        <c:forEach var="tempUser" items="${users}">

                            <c:url var="updateLink" value="/user/showFormForUpdate">
                                <c:param name="userId" value="${tempUser.id}" />
                            </c:url>
                            <c:url var="deleteLink" value="/user/delete">
                                <c:param name="userId" value="${tempUser.id}" />
                            </c:url>
                            <tr>
                                <td>${tempUser.firstName}</td>
                                <td>${tempUser.lastName}</td>
                                <td>${tempUser.address.street}</td>
                                <td>${tempUser.address.city}</td>
                                <td>${tempUser.address.zipCode}</td>
                                <td><a href="${updateLink}">Aktualizuj</a> | <a
                                    href="${deleteLink}"
                                    onclick="if(!(confirm('Usunąć użytkownika z bazy?'))) return false">Usuń</a></td>
                            </tr>

                        </c:forEach>
                    </tbody>
                    <p><i>Liczba użytkowników: ${fn:length(users)}</p>
                </table>
                <button type="button" class="btn btn-primary"
                    onclick="window.location.href='showFormForAdd'; return false;">Dodaj
                    użytkownika</button>
            </div>

        </div>
    </div>
    <footer>
        <br>
        <hr>
        <center>
            <i>SimpleCRUD 2018</i>
        </center>
    </footer>
</body>
</html>

пользователь form.jsp

<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form"%>
<%@page pageEncoding="UTF-8" contentType="text/html; charset=UTF-8"%>
<!DOCTYPE html>
<html>
<head>

<link rel="stylesheet"
    href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css"
    integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm"
    crossorigin="anonymous">
<script
    src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js"
    integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl"
    crossorigin="anonymous"></script>
<title>SimpleCRUD</title>
</head>

<body>
    <nav class="navbar navbar-dark bg-primary" style="color: white">
        <h3>
            <i>SimpleCRUD</i>
            <h3>
    </nav>
    <div class="container">
        <div class="row">

            <div class="col-md-4">
                <br>
                <h3>
                    <i>Dodaj użytkownika</i>
                </h3>
                <br>
                <form:form action="saveUser" modelAttribute="user" method="POST">
                    <form:hidden path="id" />
                    <form:hidden path="address.id" />

                    <div class="form-group">
                        <label>Imię: </label>
                        <form:input class="form-control" path="firstName" />
                        <form:errors path="firstName"/>
                    </div>
                    <div class="form-group">
                        <label>Nazwisko: </label>
                        <form:input class="form-control" path="lastName" />
                            <form:errors path="lastName"/>
                    </div>
                    <div class="form-group">
                        <label>Ulica: </label>
                        <form:input class="form-control" path="address.street" />
                        <form:errors path="address.street"/>
                    </div>
                    <div class="form-group">
                        <label>Miasto: </label>
                        <form:input class="form-control" path="address.city" />
                        <form:errors path="address.city"/>
                    </div>
                    <div class="form-group">
                        <label>Kod pocztowy: </label>
                        <form:input class="form-control" path="address.zipCode" />
                        <form:errors path="address.zipCode"/>
                    </div>

                    <input type="submit" class="btn btn-success" value="Zapisz" />
                    <a class="btn btn-primary"
                        href="${pageContext.request.contextPath}/user/list">Powrót do
                        listy</a>
                </form:form>
            </div>
        </div>
    </div>
</body>
</html>

SQL-скрипты

create table address (
id int(11) not null auto_increment,
street varchar(45) default null,
city varchar(45) default null,
zip_code varchar(45) default null,
primary key (id)
);

create table user (
id int(11) not null auto_increment,
first_name varchar(45) default null,
last_name varchar(45) default null,
address_id int(11) default null,
primary key (id),
KEY FK_ADDRESS_idx (address_id),
constraint FK_ADDRESS foreign key (address_id)
references address (id)
);

@ EDIT

Информация из консоли после сохранения пользователя и адрес в базе данных:

Hibernate: insert into address (city, street, zip_code) values (?, ?, ?)
Hibernate: insert into User (address_id, first_name, last_name) values (?, ?, ?)

Информация из консоли после удаления пользователя и «адрес» из базы данных:

Hibernate: delete from User where id=?

После удаления пользователя из таблицы информация об удалении адреса отсутствует, как указано выше.

Ответы [ 2 ]

0 голосов
/ 28 августа 2018

Если вы хотите также удалить значение адреса при удалении данных пользователя, то вместо использования запроса сначала нужно извлечь объект пользователя на основе userId, а затем удалить объект,

Итак,Ваш код для удаления пользователя будет выглядеть примерно так:

public void delete(int id) {
        User user = getOne(id); // method present in Abstract Dao class to find the object based on Id
        Session session = sessionFactory.getCurrentSession();
        session.delete(user);
    }
0 голосов
/ 26 августа 2018

Сделать User & Address таблицу двунаправленной.

В Address.java добавить ниже свойство с getter / setter

@OneToOne(mappedBy="address") // variable name of join property Address in User.java
private Address address;

Когда В случае, если мы не можем изменить Address.java, вы можете использовать следующий подход для удаления сирот.

В User.java

@OneToOne(cascade = CascadeType.ALL, orphanRemoval=true)
@JoinColumn(name = "address_id")
private Address address;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...