在某些情况下,我想检索数据,但是在返回数据之前,我想在不保存/持久化的情况下进行更改。
这是我的休息控制器:
@RestController
@RequestMapping("api/drawing-releases")
@CrossOrigin("*")
public class DrawingReleaseRestController {
@Autowired
private DrawingReleaseService service;
@RequestMapping(method = RequestMethod.GET, value = "/{id}")
@JsonView(View.DrawingReleaseView.class)
public ResponseEntity<DrawingRelease> getWithId(@PathVariable int id) throws EntityNotFoundException {
return new ResponseEntity<>(service.getByID(id),HttpStatus.OK);
}
}
这是服务实现:
@Service
public class DrawingReleaseServiceImpl extends DrawingFunctions implements DrawingReleaseService {
/**
* Logging Manager
*/
private static final Logger LOGGER=LogManager.getLogger();
@Autowired
private DrawingReleaseRepository repository;
@Override
public DrawingRelease getByID(int id) throws EntityNotFoundException {
Optional<DrawingRelease> opt = repository.findById(id);
...
// manipulate the data here
...
return opt.get();
}
}
最初,我在服务上有@Transactional
注释。通过删除而不是使用getByID
方法,我首先想到的是会话将按照答案here的指示打开和关闭存储库。
那没有用,我在注释中看到“会话在HTTP请求处理的整个过程中持续进行”。因此,在我添加的服务中
@Autowired
private EntityManager em;
,然后在我添加的getByID
方法中
em.close();
在进行任何更改之前。但是,我所做的任何更改仍将保留。
有什么方法可以在服务层中进行未保存的更改?我想我可以创建一些映射实体(但不是实体)的POJO,然后复制数据并返回那些对象,但是看来我不必要做类似的事情。
答案 0 :(得分:1)
是的,您可以从持久性上下文中detach
实体:https://docs.oracle.com/javaee/7/api/javax/persistence/EntityManager.html#detach-java.lang.Object-
答案 1 :(得分:1)
您说要获取一个实体,然后更改数据,然后在不保留该实体的情况下返回它,但是恕我直言,您不应该为此使用实体。您为什么要更改数据以及用户将如何处理数据,因为数据不再代表数据库中的内容。将要进行哪些其他更改,或者哪些其他假设(这是一个数据库对象)将无效?
如果您正在使用数据库对象派生其他对象,则您应该为此使用其他类。这很常见,称为数据传输对象(DTO),可以直接使用投影从spring-data-jpa创建它们。您的Dto对象将一个实体作为构造函数,并填写想要从该实体获取的任何属性。 Dto不是持久对象,因此保存它周围没有任何问题。
更清晰,更易理解的设计,并且与SOLID Principles and code structure保持一致。