2016-12-23 9 views
0

私はJAX-RS APIを設計しています。EntityManager#は識別不可能なエンティティとマージしてはいけませんか?

POST /myentities 
PUT /myentities/{myentityId} 

私はこのようにしました。

@PUT 
@Path("/{myentityId: \\d+}") 
@Consumes(...) 
@Transactional 
public Response updateMyentity(
    @PathParam("myentityId") final long myentityId, 
    final Myentity myentity) { 
    if (!Objects.equal(myentitiyId, myentity.getId())) { 
     // throw bad request 
    } 
    entityManager.merge(myentity); 
    return Response.noContent().build(); 
} 

突然私は自分自身に不思議と疑問を抱く。

クライアントは、次のリクエスト

PUT /myentities/101 HTTP/101 
Host: .. 

<myentity id=101> 
</myentity> 

を呼び出すには、要求が101によって識別されていないリソースが存在しない場合でも処理されることは可能ですか?

私はテストを実行しました。

acceptEntityManager(entityManager -> { 
    // persist 
    final Device device1 = mergeDevice(entityManager, null); 
    entityManager.flush(); 
    logger.debug("device1: {}", device1); 
    assertNotNull(device1.getId()); 
    // remove 
    entityManager.remove(device1); 
    entityManager.flush(); 
    assertNull(entityManager.find(Device.class, device1.getId())); 
    // merge again, with non existing id 
    final Device device2 = entityManager.merge(device1); 
    entityManager.flush(); 
    logger.debug("device2: {}", device2); 
}); 

2番目のマージが動作し、新しいIDが割り当てられていることがわかりました。 これは正常ですか? EntityManager#merge操作を拒否してはいけませんか?

は、それがどのクライアントが

PUT /myentities/<any number> 

を呼び出すことにより、APIを攻撃できることを意味しますか?

答えて

0

私はこの権利を理解していれば、これはマージがうまくいく方法です。 mergeエンティティクラスの新しいインスタンスを作成し、指定したエンティティの現状をコピーします(ケースではdevice1)。その新しいインスタンスをトランザクションに追加します。 新しいインスタンスが管理され、古いインスタンスは、トランザクションで更新されていないとflushを介してデータベースに伝播されることはありません - 。運転

をですから、entityManager.remove(device1);
final Device device2 = entityManager.merge(device1);はそれの新しいコピーを追加する呼び出しでデータベースからdevice1を削除しながら、(新しいとID)をデータベースに追加します。device1の変更はトランザクション内で追跡されないため、データバに反映されません一度あなたのテーブルをflush。一方、device2への変更はトランザクションで追跡されます。

関連する問題