[英]JPA + Spring Boot: TransactionRequiredException on CRUD operations
[英]Spring Data REST JPA: Integrate automatic CRUD operations with manual controller
我正在使用Spring Data REST JPA構建RESTful Web服務。 到目前為止,Spring會為所有可能的方法自動生成所有響應,並列出所有可用資源甚至搜索它們:
@RepositoryRestResource(collectionResourceRel = "scans", path = "scans")
public interface ScanRepository extends PagingAndSortingRepository<Scan, Long> {
List<Scan> findByProjectId(@Param("pid") String pid);
}
現在,我想修改“僅”返回到POST請求的內容,同時保留對所有其他請求的完整支持。 我以為會為此目的創建一個控制器,如下所示:
@Controller
public class ScanController {
@RequestMapping(value = "/scans", method = POST, produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody Result parseScan(@RequestParam String projectId, @RequestParam String tool) {
return null;
}
但是,當我這樣做時,對於所有其他方法和搜索等的JPA數據自動生成的響應將不復存在。 例如,如果轉發GET請求,則會顯示“不允許使用方法”。
此外,如何從控制器訪問JSON有效負載?
更新
現在,對於在我自己的控制器中未手動處理的請求,僅公開資源之一會返回默認方法。 但是,我不知道為什么其他資源會這樣做,為什么不會發生這種情況。*盡管它們的唯一區別只是它們的實體屬性不同。
以下特定資源是對我在控制器中聲明的不是POST scan /或GET / scan ///的所有內容返回默認請求處理程序的資源:
@Controller
public class ScanController {
@Autowired
private ScanService scanService;
@RequestMapping(
value = "/scan",
method = POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody
Scan parseScan(@RequestBody Scan rbody) {
<...do something...>
}
@RequestMapping(value = "/scans/{id}/{totvuln}/{nth}", method = RequestMethod.GET,
produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody
Scan getScan(@PathVariable String id, @PathVariable int totvuln, @PathVariable int nth) throws ScanNotFound {
<...do something...>
}
它具有以下存儲庫接口:
public interface ScanRepository extends PagingAndSortingRepository<Scan, Long> {}
以及以下服務:
@Service
public class ScanServiceImpl implements ScanService {
@Resource
private ScanRepository scanRepository;
@Resource
private ResultRepository resultRepository;
@Override
@Transactional
public Scan create(Scan shop) {
<some code>
}
@Override
@Transactional
public Scan findById(long id) {
<some code>
}
@Override
@Transactional(rollbackFor = ScanNotFound.class)
public Scan delete(long id) throws ScanNotFound {
<some code>
}
@Override
@Transactional
public List<Scan> findAll() {
<some code>
}
@Override
@Transactional(rollbackFor = ScanNotFound.class)
public Scan update(Scan scan) throws ScanNotFound {
<some code>
}
}
資源本身具有以下屬性:
@Entity
public class Scan {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private Long projectId;
@OneToMany
private Collection<Result> result;
private int totV;
<getters and setters>
}
盡管以下半相同的資源“規則”不返回任何默認請求處理程序。 對於POST / rule以外的任何內容,它返回“不允許的方法”:
@Controller
public class RulesController {
@Autowired
private RulesService rService;
@Resource
private ScanRepository scanRepository;
@RequestMapping(
value = "/rule",
method = POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody
Rules generateRules(@RequestBody Scan rbody) throws Exception {
<do something>
}
}
它具有相同的存儲庫接口:
public interface RulesRepository extends PagingAndSortingRepository<Rules, Long> {}
以及相同的服務實現:
@Service
public class RulesServiceImpl implements RulesService {
@Resource
private RulesRepository rRepository;
@Resource
private ResultRepository resultRepository;
@Override
@Transactional
public Rules create(Rules shop) {
<do something>
}
@Override
@Transactional
public Rules findById(long id) {
<do something>
}
@Override
@Transactional(rollbackFor = RulesNotFound.class)
public Rules delete(long id) throws RulesNotFound {
<do something>
}
@Override
@Transactional
public List<Rules> findAll() {
<do something>
}
@Override
@Transactional
public Rules findByScanId(long id) throws RulesNotFound {
<do something>
}
@Override
@Transactional(rollbackFor = RulesNotFound.class)
public Rules update(Rules scan) throws RulesNotFound {
<do something>
}
}
資源規則本身具有以下屬性:
@Entity
public class Rules {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@OneToOne
private Scan scan;
@OneToMany
private Collection<Result> result;
private String rules;
<getters and setters>
}
對於未在我的控制器類中手動指定的任何請求,Spring為什么不對“規則”也公開默認請求處理程序?
如果您能指出原因,我將不勝感激。 非常感謝!
我已經弄清楚了如何從控制器訪問JSON負載:
@RequestMapping(
value = "/scan",
method = POST,
consumes = MediaType.APPLICATION_JSON_VALUE,
produces = {MediaType.APPLICATION_JSON_VALUE})
public @ResponseBody
Scan parseScan(@RequestBody Scan rbody) {
Scan scan = new Scan();
scan.setProjectId(rbody.getProjectId());
scan.setTool(rbody.getTool());
return scan;
}
我還意識到實際上我的控制器未處理的每個請求實際上都已支持自動CRUD操作:我只是在請求錯誤的URL。 通過請求“ curl http:// localhost:8080 ”,我可以使用正確的URL列表
但是,可以使用以下命令設置任何自動生成的操作的首選URL
@RepositoryRestResource(collectionResourceRel = pref_URL_suffix, path = pref_URL_suffix)
^^在我嘗試的所有更改中,上面的那一行都丟失了。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.