Jpa 实体管理器:em.merge()创建新记录而不是更新

Jpa 实体管理器:em.merge()创建新记录而不是更新,jpa,entitymanager,Jpa,Entitymanager,我正在使用netbeans开发一个EJB应用程序,用于管理酒店预订。我意识到,如果实体的主键或@Id设置为autogenerated,实体管理器的em.merge()函数将在数据库中插入一条新记录,而不是进行更新。 我有两个实体-预订和客房。预订的ID是自动生成的,而房间的ID不是自动生成的。会话bean中的相同merge()函数为预订插入新行,但为房间更新 我的实体bean和会话bean如下所示:- 预订实体 @SequenceGenerator(name="booking_seq", ini

我正在使用netbeans开发一个EJB应用程序,用于管理酒店预订。我意识到,如果实体的主键或@Id设置为autogenerated,实体管理器的em.merge()函数将在数据库中插入一条新记录,而不是进行更新。 我有两个实体-预订和客房。预订的ID是自动生成的,而房间的ID不是自动生成的。会话bean中的相同merge()函数为预订插入新行,但为房间更新

我的实体bean和会话bean如下所示:-

预订实体

@SequenceGenerator(name="booking_seq", initialValue=1, allocationSize=100)
@Entity
@NamedQueries({@NamedQuery(name="Booking.getAll",query="SELECT e FROM Booking e order by e.bookingId")})
public class Booking implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="booking_seq")
    @Column
    private int bookingId;
    @Column
    private int roomId;
    @Column
    private int customerId;
    @Column
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date arrival_date;
    @Column
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date departure_date;

    public Booking(int bookingId, int roomId, int customerId, Date arrival_date, Date departure_date) {
        this.bookingId = bookingId;
        this.roomId = roomId;
        this.customerId = customerId;
        this.arrival_date = arrival_date;
        this.departure_date = departure_date;
    }

    public Booking() {
    }

    public int getBookingId() {
        return bookingId;
    }

    public void setBookingId(int bookingId) {
        this.bookingId = bookingId;
    }

    public int getRoomId() {
        return roomId;
    }

    public void setRoomId(int roomId) {
        this.roomId = roomId;
    }

    public int getCustomerId() {
        return customerId;
    }

    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }

    public Date getArrival_date() {
        return arrival_date;
    }

    public void setArrival_date(Date arrival_date) {
        this.arrival_date = arrival_date;
    }

    public Date getDeparture_date() {
        return departure_date;
    }

    public void setDeparture_date(Date departure_date) {
        this.departure_date = departure_date;
    }


}
@Stateless
public class BookingDAO implements BookingDAOLocal {
  @PersistenceContext
    private EntityManager em;

   @Override
    public void addBooking(Booking booking) {
        em.persist(booking);

    }

     @Override
    public void editBooking(Booking booking) {

        em.merge(booking);

    }
      @Override
    public void deleteBooking(int bookingId) {

        em.remove(em.find(Booking.class, bookingId));


    }
}
房间实体

@Entity
@Table
@NamedQueries({@NamedQuery(name="Room.getAll",query="SELECT e FROM Room e order by e.roomId")})
public class Room implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
     @Column
    private int  roomId;
     @Column
    private String roomType;
      @Column
    private String bedType;
       @Column
    private double tariff;

    public Room() {
    }

    public Room(int roomId, String roomType, String bedType, double tariff) {
        this.roomId = roomId;
        this.roomType = roomType;
        this.bedType = bedType;
        this.tariff = tariff;
    }

    public int getRoomId() {
        return roomId;
    }

    public void setRoomId(int roomId) {
        this.roomId = roomId;
    }

    public String getRoomType() {
        return roomType;
    }

    public void setRoomType(String roomType) {
        this.roomType = roomType;
    }

    public String getBedType() {
        return bedType;
    }

    public void setBedType(String bedType) {
        this.bedType = bedType;
    }

    public double getTariff() {
        return tariff;
    }

    public void setTariff(double tariff) {
        this.tariff = tariff;
    }

}
@Stateless
public class RoomDAO implements RoomDAOLocal {

    @PersistenceContext
    private EntityManager em;

    @Override
    public void addRoom(Room room) {
        em.merge(room);
         em.flush();
    }

    @Override
    public void editRoom(Room room) {
        em.merge(room);
         em.flush();
    }
     @Override
        public void deleteRoom(int roomId) {

        em.remove(em.find(Room.class, roomId));

    }

}
预订实体的会话bean

@SequenceGenerator(name="booking_seq", initialValue=1, allocationSize=100)
@Entity
@NamedQueries({@NamedQuery(name="Booking.getAll",query="SELECT e FROM Booking e order by e.bookingId")})
public class Booking implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="booking_seq")
    @Column
    private int bookingId;
    @Column
    private int roomId;
    @Column
    private int customerId;
    @Column
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date arrival_date;
    @Column
    @Temporal(javax.persistence.TemporalType.DATE)
    private Date departure_date;

    public Booking(int bookingId, int roomId, int customerId, Date arrival_date, Date departure_date) {
        this.bookingId = bookingId;
        this.roomId = roomId;
        this.customerId = customerId;
        this.arrival_date = arrival_date;
        this.departure_date = departure_date;
    }

    public Booking() {
    }

    public int getBookingId() {
        return bookingId;
    }

    public void setBookingId(int bookingId) {
        this.bookingId = bookingId;
    }

    public int getRoomId() {
        return roomId;
    }

    public void setRoomId(int roomId) {
        this.roomId = roomId;
    }

    public int getCustomerId() {
        return customerId;
    }

    public void setCustomerId(int customerId) {
        this.customerId = customerId;
    }

    public Date getArrival_date() {
        return arrival_date;
    }

    public void setArrival_date(Date arrival_date) {
        this.arrival_date = arrival_date;
    }

    public Date getDeparture_date() {
        return departure_date;
    }

    public void setDeparture_date(Date departure_date) {
        this.departure_date = departure_date;
    }


}
@Stateless
public class BookingDAO implements BookingDAOLocal {
  @PersistenceContext
    private EntityManager em;

   @Override
    public void addBooking(Booking booking) {
        em.persist(booking);

    }

     @Override
    public void editBooking(Booking booking) {

        em.merge(booking);

    }
      @Override
    public void deleteBooking(int bookingId) {

        em.remove(em.find(Booking.class, bookingId));


    }
}
房间实体的会话bean

@Entity
@Table
@NamedQueries({@NamedQuery(name="Room.getAll",query="SELECT e FROM Room e order by e.roomId")})
public class Room implements Serializable {
    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
     @Column
    private int  roomId;
     @Column
    private String roomType;
      @Column
    private String bedType;
       @Column
    private double tariff;

    public Room() {
    }

    public Room(int roomId, String roomType, String bedType, double tariff) {
        this.roomId = roomId;
        this.roomType = roomType;
        this.bedType = bedType;
        this.tariff = tariff;
    }

    public int getRoomId() {
        return roomId;
    }

    public void setRoomId(int roomId) {
        this.roomId = roomId;
    }

    public String getRoomType() {
        return roomType;
    }

    public void setRoomType(String roomType) {
        this.roomType = roomType;
    }

    public String getBedType() {
        return bedType;
    }

    public void setBedType(String bedType) {
        this.bedType = bedType;
    }

    public double getTariff() {
        return tariff;
    }

    public void setTariff(double tariff) {
        this.tariff = tariff;
    }

}
@Stateless
public class RoomDAO implements RoomDAOLocal {

    @PersistenceContext
    private EntityManager em;

    @Override
    public void addRoom(Room room) {
        em.merge(room);
         em.flush();
    }

    @Override
    public void editRoom(Room room) {
        em.merge(room);
         em.flush();
    }
     @Override
        public void deleteRoom(int roomId) {

        em.remove(em.find(Room.class, roomId));

    }

}

事实上,我现在得到了答案。对于editBooking()方法,我使用了与addBooking()相同的代码。在addBooking()中,我没有setBookingId()方法调用,因为它是自动生成的。只需要为编辑方法添加额外的部分

   else if ("Add".equalsIgnoreCase(action) || "Edit".equalsIgnoreCase(action) )
        {

           try {

         arrival_date = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH).parse(request.getParameter("arrival_date"));
         departure_date = new SimpleDateFormat("MM/dd/yyyy", Locale.ENGLISH).parse(request.getParameter("departure_date"));
       }
       catch(ParseException e) {
        e.printStackTrace();
    }



        Booking booking = new Booking();
if("Edit".equalsIgnoreCase(action))
{
int bookingId=Integer.parseInt(request.getParameter("bookingId"));
 booking.setBookingId(bookingId);

}
        booking.setRoomId(Integer.parseInt(request.getParameter("roomId")));
        booking.setCustomerId(customerId);
        booking.setArrival_date(arrival_date);
        booking.setDeparture_date(departure_date);

      if("Add".equalsIgnoreCase(action))
        bookingDao.addBooking(booking);
      else 
        bookingDao.editBooking(booking);

                   request.setAttribute("allBookings", bookingDao.getAllBookings());
           request.getRequestDispatcher("booking_details.jsp").forward(request, response);



        }

您没有尝试更新记录,而是尝试持久化同一个文件室,而不是尝试此操作

 @Override
public void editRoom(Room room) {
    Room r-= em.merge(room);
    r.setRoomType("2bed"); // your own update field other than the @Id (Primary key)
    em.flush();
    // you can retun the updated employee.
}

您正在尝试合并的预订已具有有效Id?我们需要了解您如何获取并填充传递到
merge()
的对象。实际上,我现在已经得到了答案。对于editBooking()方法,我使用了与addBooking()相同的代码。在addBooking()中,我没有setBookingId()方法调用,因为它是自动生成的。只需要添加编辑方法的额外部分。我在答案中添加的修改代码。