我正在做一个小的测试项目,将数据持久化到一个简单的数据库中。我在设置数据实体时遇到了困惑和问题,需要一些帮助。
我将此开发为Spring Boot Java项目,并使用JPA实现持久性功能。我对JPA不是很熟悉。
考虑以下模拟模式:
任务:
<simple data fields omitted>
collection of TaskNote items
collection of StateChangeHistory items
reference to a "parent" Task item (can be null)
collection of Task "child" items (may be empty)
任务说明:
<simple data fields omitted>
状态更改历史:
<simple data fields omitted>
我不确定注释和构造这些类以促进这种安排的正确方法。我也不确定其中一些关系本质上应该是单向的还是双向的。我看过关于建立单向和双向关系的各种方法的文章,但我仍然感到困惑,不确定何时应该使用特定的方法。
以下是我目前的情况:
任务java:
@Entity
public class Task extends AbstractEntity {
// Simple fields omitted.
@OneToMany(mappedBy = "taskId", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<TaskNote> notes = new LinkedList<>();
@OneToMany(mappedBy = "taskId", fetch = FetchType.LAZY, cascade = CascadeType.ALL)
private List<StateChangeHistory> stateHistory = new LinkedList<>();
// Have not yet attempted to implement parent and children.
}
任务说明。java:
@Entity
public class TaskNote extends AbstractEntity {
// Simple fields omitted.
@ManyToOne
@JoinColumn(name = "taskId")
private Task task;
}
StateChangeHistory.java:
@Entity
public class StateChangeHistory extends AbstractEntity {
// Simple fields omitted.
@ManyToOne
@JoinColumn(name = "taskId")
private Task task;
}
抽象实体。java:
@MappedSuperclass
public abstract class AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
public Long getId() {
return id;
}
// Other items omitted.
}
当我试图运行应用程序(目前仍然是非常基本的)只是为了看看会发生什么时,有大量控制台输出,但吸引我眼球的是以下内容:
...
[WARN ] 2020-11-19 14:06:17.747 [restartedMain] AnnotationConfigServletWebServerApplicationContext - Exception encountered during context initialization - cancelling refresh attempt: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.mycompany.tasks.backend.entity.TaskNote.taskId in com.mycompany.tasks.backend.entity.Task.notes
...
[ERROR] 2020-11-19 14:06:17.794 [restartedMain] SpringApplication - Application run failed
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: mappedBy reference an unknown target entity property: com.mycompany.tasks.backend.entity.TaskNote.taskId in com.mycompany.tasks.backend.entity.Task.notes
...
不知道这意味着什么,但它与我的实体类有关。我还想知道我的POM文件中是否缺少某些东西,或者是否缺少某种配置。正如我所说,我不熟悉Java中的JPA或数据持久性。
基础知识。所以,就像我说的,没有足够的信息来解决你的问题,因为我没有得到问题。然而,这里有一个2分钟的Spring数据Jpa课程。抽象实体:
@MappedSuperclass
public abstract class AbstractEntity {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long id;
public Long getId() {
return id;
}
}
A任务:
@Entity
public class Task extends AbstractEntity {
@OneToMany(mappedBy = "task")
List<TaskNote> notes;
@OneToMany(mappedBy = "task")
List<StateChangeHistory> stateHistory;
}
任务说明
@Entity
public class TaskNote extends AbstractEntity {
@ManyToOne
Task task;
}
状态变化历史
@Entity
public class StateChangeHistory extends AbstractEntity {
@ManyToOne
Task task;
}
应用程序的一个非常重要的配置。属性。
spring.jpa.show-sql=true
一个应用程序:
@Override
public void run(ApplicationArguments args) throws Exception {
save();
Task task = taskRepo.findById(1L).get();
System.out.println("after findById");
System.out.println(task);
System.out.println("after print task");
System.out.println(task.notes);
}
private void save() {
// save ...
Task task = taskRepo.save(new Task());
TaskNote taskNote = new TaskNote();
taskNote.task = task;
taskNoteRepo.save(taskNote);
StateChangeHistory stateChangeHistory = new StateChangeHistory();
stateChangeHistory.task = task;
stateChangeHistoryRepo.save(stateChangeHistory);
}
输出:
2020-11-19 15:06:19.114 INFO 2156 --- [ main] jpatest.JpatestApplication : Started JpatestApplication in 1.798 seconds (JVM running for 2.252)
Hibernate: call next value for hibernate_sequence
Hibernate: insert into task (id) values (?)
Hibernate: call next value for hibernate_sequence
Hibernate: insert into task_note (task_id, id) values (?, ?)
Hibernate: call next value for hibernate_sequence
Hibernate: insert into state_change_history (task_id, id) values (?, ?)
Hibernate: select task0_.id as id1_1_0_ from task task0_ where task0_.id=?
after findById
jpatest.Task@fd53053
after print task
2020-11-19 15:06:19.171 INFO 2156 --- [ main] ConditionEvaluationReportLoggingListener :
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-11-19 15:06:19.185 ERROR 2156 --- [ main] o.s.boot.SpringApplication : Application run failed
java.lang.IllegalStateException: Failed to execute ApplicationRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:798) [spring-boot-2.4.0.jar:2.4.0]
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:785) [spring-boot-2.4.0.jar:2.4.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:333) [spring-boot-2.4.0.jar:2.4.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1309) [spring-boot-2.4.0.jar:2.4.0]
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1298) [spring-boot-2.4.0.jar:2.4.0]
at jpatest.JpatestApplication.main(JpatestApplication.java:13) [classes/:na]
Caused by: org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: jpatest.Task.notes, could not initialize proxy - no Session
细节:
List
为@OneTo多国
关系,因为它们实际上只是只读查询字段。mapdBy
注释说实体TaskNote
或StateChange历史
是关系的所有者
,并且只有对关系所有者所做的更改才会被持久化。这些实体如您所见被显式创建和持久化。LAZY
时,您不需要声明它。LAZY
时,除非您明确告诉JPA这样做,否则不会读取关系,并且默认的JpaRepository
接口中没有任何内容可以为您执行此操作。LAZY
只读字段而没有显式为其编写查询时,您将得到可怕的LazyLaunalizationException
。对父任务项的引用中
可以为空(可以为空)让我感到困惑。这是一个不能为空的外键。请参阅ACID主体。cascade=CascadeType。ALL
如果不在关系的所有者上,则没有任何意义,因此添加它对本示例没有影响。@Join
注释并使cascade
注释做有趣的事情,但在尝试有趣的东西之前,您最好先掌握基础知识。当我们使用EclipseLink为JPA实体使用静态编织时,我们的应用程序中就会出现异常。 该应用程序是一个web应用程序,使用SpringDataJPA和SpringDataRESTWebMVC提供CRUD功能来更改实体。 当实体类没有通过编织处理时,它就工作了。但一旦我们使用编织实体,我们就会得到: .. 当JSON响应应包含一个实体时,就会发生这种情况。实体非常简单,只有两个属性,没有关联等
我有3个实体- > 课程 组件 时间线课程是一个独立的实体,具有以下属性:课程-(id Integer主键,Course_name) @ Id @ Column(name = " Id ")Integer courseId;@Column(name = "course_name ")字符串course _ name; 接下来是另一个实体模块,模块中的每一行都与一门课程相关,因此模块和课程之间存在一
我有两个实体类它只有一个字段叫做和第二个实体它有两个字段和。数据库结构 我正在创建一个简单的CRUD web-app,但是update方法不是更新实体,而是在DB中插入新值。我检查了一下,当用户点击指定菜单上的更新时,第一个实体的id和它的配料id也会被预先定义。我是spring boot和thymeleaf的新手,不知道当您有一个以上的实体时如何使用JPA。 菜单实体: 配料实体: 控制器(仅更
问题内容: 我只是在Glassfish 3(持久性提供程序是EclipseLink)上运行的简单Java Web应用程序中了解JPA。到目前为止,我真的很喜欢它(除了netbeans / glassfish交互中的错误),但是我想做到的事情我不确定该怎么做。 我有一个映射到数据库表的实体类(文章)。我正在尝试对返回已计算列的数据库进行查询,但无法弄清楚如何设置Article类的属性,以便在调用查询
问题内容: 我正在开发Spring and Stripes网络应用程序的JPA(Hibernate实现)。我有许多JPA实体,它们具有以下共同的字段,用于审计和查询目的: createdBy-创建实体的人的用户ID。createdOn-创建实体的日期更新By-上一次更新实体的用户的用户ID updateOn- 实体上一次更新的日期 我已经使我的应用程序正常工作,以便在实体持久化时会自动设置crea
假设我的数据库中有一个表。每个有许多,每个可能有许多。这将是一个经典的-相关性,因此,如果我想在我的Spring Boot JPA中描述它,我可以如下所示: 设置我的实体并将它们连接起来: 实现我的存储库: 现在让我们假设我想指定每个用户在这个项目中的角色。因此,我将有一个表,它使用以下实体表示来指定不同的角色: 但这与我的用户和项目有什么联系呢?所以我想展示的是,一个用户可以在一个项目中有一个角