gpt4 book ai didi

jsf - JPA更新一对一关联对象导致重复条目异常

转载 作者:行者123 更新时间:2023-12-04 19:36:24 26 4
gpt4 key购买 nike

我使用 JSF 2.0、Tomcat 7.x 和 EclipseLink 作为 JPA 提供程序。我想用 onetoone 关联更新一个实体实例,更准确地说,一个 Booking 有一个名为 booker 的 User 属性。不幸的是,如果我调用我的 updateBooking() Api 方法,EclipseLink 想要创建一个新的预订者而不是仅仅使用已经存在的用户。添加了 Eclipse 控制台堆栈跟踪和相关代码片段 - 预先感谢您提供一些提示!

堆栈跟踪:

Caused by: Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.1.v20111018-r10243): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'EMAIL'
Error Code: 1062
Call: INSERT INTO user (EMAIL, NAME, PASSWORD) VALUES (?, ?, ?)
bind => [3 parameters bound]
Query: WriteObjectQuery(LogString User - id: 1; name: 1; email: 1;)
at org.eclipse.persistence.exceptions.DatabaseException.sqlException(DatabaseException.java:324)
at org.eclipse.persistence.internal.databaseaccess.DatabaseAccessor.executeDirectNoSelect(DatabaseAccessor.java:840)
...
Caused by: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Duplicate entry '1' for key 'EMAIL'
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source)

开发 Controller .java

public String testUpdateBooking(){
String str = "/development.xhtml?faces-redirect=true";
try {
Integer bookingId = 22;
Integer bookerId = 1;
BookerApi api = new BookerApi();
Booking booking = api.readBooking(bookingId);
User booker = api.readUser(bookerId);
booking.setBooker(booker);
api.updateBooking(booking);
message = "DevelopmentController.testUpdateBooking() " + booking;
} catch (RuntimeException exc){
message = "EXCEPTION DevelopmentController.testUpdateBooking();";
exc.printStackTrace();
}
return str;
}

布克API.java

public void updateBooking(Booking booking){
emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
Booking persBooking = em.find(Booking.class, booking.getId());
persBooking.setCourtNo(booking.getCourtNo());
persBooking.setStart(booking.getStart());
persBooking.setEnd(booking.getEnd());
persBooking.setBooker(booking.getBooker());
em.getTransaction().commit(); // haendelt update implizit, kracht
em.clear();
emf.close();
}

实体布克属性:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
Integer id;
@Temporal(TemporalType.DATE)
@Column(nullable = false)
Date start;
@Temporal(TemporalType.DATE)
@Column(nullable = false)
Date end;
@Column(nullable = false)
Integer courtNo;
@OneToOne(fetch = FetchType.EAGER) // Mueller S. 105, 109
@JoinColumn(name = "user")
User booker;

实体用户属性:

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
@Column(unique = true, nullable = false)
private String name;
@Column(nullable = false)
private String password; // TODO verschluesseln
@Column(unique = true, nullable = false)
private String email;

最佳答案

很多事情:
1:修复
您不需要在 jpa 中编写任何 CRUD 方法,EntityManager 提供了所有需要的方法

public void updateBooking(Booking booking){
emf = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.merge(booking);
em.getTransaction().commit();
em.close();
emf.close();

但是

你不应该这样处理交易,交易应该在服务层而不是数据访问层打开。事实上,如果你有一个使用 @transactional 注释的容器(意味着使用 Spring 或 Java EE 服务器),它应该由容器管理。如果您绝对想手动管理它,则必须妥善处理最终的异常并在遇到异常时回滚。 EntityManager 和底层事务通常具有相同的范围/生命周期。

此外,对于所有应用程序,您应该只有一个 EntityManagerFactory。

否则你不需要在这里指定抓取类型,oneToOne 关联总是被热切抓取。

关于jsf - JPA更新一对一关联对象导致重复条目异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16113179/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com