【问题标题】:REST Web Service GET method can persist entityREST Web Service GET 方法可以持久化实体
【发布时间】:2018-01-25 01:24:18
【问题描述】:

在我尝试使用 NetBeans 8.2 研究 REST Web 服务时,我创建了一个基于提供的 sample 数据库自动创建的实体。

在测试方法 find(注释为 @GET)的 URI 时,我试图混淆或掩盖我正在检索的实体的属性之一,方法是在从数据库中检索到实体后对其进行更改。

这里是改变了查找方法:

@GET
@Path("{id}")
@Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON})
public Manufacturer find(@PathParam("id") Integer id) {
    Manufacturer mfg = super.find(id);

    // seems like this line merges the entity in the database. Why?! 
    mfg.setAddressline2("Suite ABC"); 

    return mfg; 
    // return super.find(id); -- this line would prove the obvious that somehow the entity was merged
}

在调用 find(id) 之前,数据库中 Addressline2 的值类似于“Suite 100”。

为了测试查找,我在浏览器上使用了这个 URL:

http://localhost:8080/REST01/rest/manufacturers/19985678 其中 19985678 是表的 PK 值。

输出是:

<manufacturer>
<addressline1>5 81st Street</addressline1>
<addressline2>**Suite ABC**</addressline2>
<city>Mountain View</city>
<email>happysearching@example.com</email>
<fax>408-555-0103</fax>
<manufacturerId>19985678</manufacturerId>
<name>Happy End Searching</name>
<phone>650-555-0102</phone>
<rep>John Snow</rep>
<state>CA</state>
<zip>94043</zip>
</manufacturer>

令我惊讶的是,当我只调用 GET 方法时,我看到数据库中的值更改为修改后的值 - Suite ABC。

我已经在 Oracle 数据库以及 GlassFish 和 WebLogic 服务器上进行了尝试。症状一致。

这里是持久化配置,没有添加到原版 xml 中。

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<persistence xmlns="http://xmlns.jcp.org/xml/ns/persistence" 
 xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" version="2.1" 
 xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence 
 http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="REST01PU" transaction-type="JTA">
<jta-data-source>jdbc/sample</jta-data-source>
<exclude-unlisted-classes>false</exclude-unlisted-classes>
<properties/>
</persistence-unit>
</persistence>

有人可以解释在幕后持续存在实体的机制吗?

非常感谢,

【问题讨论】:

    标签: java rest jpa service get


    【解决方案1】:

    数据库受到影响,因为当您调用 Manufacturer mfg = super.find(id); mfg 对象成为实体管理器的托管对象。这意味着任何直接的更改都会反映在数据库中。

    有一些方法可以断开实体。例如,您可以调用 super.detach(mfg) (我假设在 super 中存在实体管理器方法访问)

    【讨论】:

    • 谢谢你,恩里克。我以前从未尝试过更改 EntityManager 找到的对象,这让我感到惊讶,因为我认为 @GET 会保证分离。 ......我猜是我的隧道视野。干杯!
    • 另外,回到基础,一旦找到,实体处于托管状态,这确保了持久性。完全被忽视了。
    猜你喜欢
    • 2023-03-09
    • 1970-01-01
    • 2011-12-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 2012-11-14
    相关资源
    最近更新 更多