为什么实体对象在方法返回后会被分离?(春季数据JPA)



已解决:问题是around方面以某种方式修改了代理中的返回值。很抱歉出现无法回答的问题。也许有人知道我的错。谢谢你的帮助!

我的spring-boot控制台应用程序有问题。我还使用spring数据jpa来持久化。一切都很好,我可以保存和查找实体,但当服务类方法返回实体时,它将被分离。当我想使用返回的对象时,由于对象值为null,应用程序失败。

这只是一个例子。

@Entity
@Table(name = "person")
public class Person {
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Id
private int id;
private String name;
@Convert(converter = LocalDateAttributeConverter.class)
private LocalDate birth;
public Person() {
}
//getter, setter..
}
public interface PersonRepository extends CrudRepository<Person, Long> {
public Person findByName(String name);
}
public class Service {
@Autowired
private PersonRepository personRepository;
public Person findPersonByName(String name) {
return personRepository.findByName(name); // System.out.println(person.name) -> someone
}
}
public class App {
private Service service;
public void doSomething(){
Person person = service.findPersonByName("someone"); 
// System.out.println(person.name) -> nullpointerEx
}
} 
//The player like person in the exaple. I must cover some detail in the package names. 
//This is the real exception. As a say above, the code it's just a raw example. Probably don't match for this.
Hibernate: select player0_.id as id1_7_, player0_1_.email as email2_7_, player0_1_.password as password3_7_, player0_.balance as balance1_4_, player0_.birth as birth2_4_, player0_.currency as currency3_4_, player0_.name as name4_4_ from player player0_ inner join user player0_1_ on player0_.id=player0_1_.id where player0_.name=?
14:24:02.087 [main] INFO  o.s.b.a.l.ConditionEvaluationReportLoggingListener - 
Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
14:24:02.103 [main] ERROR o.s.boot.SpringApplication - Application run failed
java.lang.IllegalStateException: Failed to execute CommandLineRunner
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:787)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:768)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:322)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1226)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1215)
at com....Application.main(..Application.java:13)
Caused by: java.lang.NullPointerException: null
at com.....view.ConsoleView.printWelcomeMassege(ConsoleView.java:101)
at com.....App.createPersone(App.java:46)
at com.....App.play(App.java:33)
at com....Application.lambda$0(..Application.java:22)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:784)
... 5 common frames omitted
14:24:02.118 [main] INFO  o.s.o.j.LocalContainerEntityManagerFactoryBean - Closing JPA EntityManagerFactory for persistence unit 'default'
14:24:02.118 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown initiated...
14:24:02.165 [main] INFO  com.zaxxer.hikari.HikariDataSource - HikariPool-1 - Shutdown completed.

我该怎么处理?

我认为您缺少@Column(name = "name")Annotation

为什么实体对象在方法返回后会被分离?

因为服务未声明为事务性的。

尝试:

@Service
**@Transactional**
public class Service {
@Autowired
private PersonRepository personRepository;
public Person findPersonByName(String name) {
return personRepository.findByName(name); // System.out.println(person.name) -> someone
}
}

@Service
public class Service {
@Autowired
private PersonRepository personRepository;
**@Transactional**
public Person findPersonByName(String name) {
return personRepository.findByName(name); // System.out.println(person.name) -> someone
}
}

为了减少注释的数量并降低忘记注释的风险,您还可以使用自定义注释TransactionalService:

**@TransactionalService**
public class Service {
@Autowired
private PersonRepository personRepository;
public Person findPersonByName(String name) {
return personRepository.findByName(name); // System.out.println(person.name) -> someone
}
}

TransactionalService还配置为回滚BusinessException及其子类。

Drombler Commons库是开源的,可从Maven Central获得:

<dependency>
<groupId>org.drombler.commons</groupId>
<artifactId>drombler-commons-spring-transaction</artifactId>
<version>1.0</version>
</dependency>

但是,请注意,分离实体不会使它们为空。访问name属性时,您真的会得到NullPointerException吗?这表示找不到实体。

但是,从您的代码示例中可以看出,您通过访问未初始化的服务获得了NullPointerException。

您需要在App类中自动连接Service以消除NullPointerException:

**// Some spring annotation**
public class App {
**@Autowired**
private Service service;
public void doSomething(){
Person person = service.findPersonByName("someone"); 
// System.out.println(person.name) -> nullpointerEx
}
} 

最新更新