Java 按组列出的JPA实体的辅助ID

Java 按组列出的JPA实体的辅助ID,java,spring,hibernate,rest,jpa,Java,Spring,Hibernate,Rest,Jpa,假设有2个JPA实体: public class Person { @Id @GeneratedValue(strategy = GenerationType.AUTO) private Integer id; @ManyToOne @JoinColumn(name = "CITY_ID") private City city; @Temporal(TemporalType.TIMESTAMP) private Date cre

假设有2个JPA实体:

public class Person {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @ManyToOne
    @JoinColumn(name = "CITY_ID")
    private City city;

    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    String name;
}

public class City {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;

    @OneToMany(mappedBy = "city")
    List<Person> people;
}
假设来自rest api控制器的响应为:

[
    { id : 11, city_id: 3, created_at: 1445831581186, name: 'Michael' },
    { id : 19, city_id: 3, created_at: 1446831581186, name: 'Jennifer' },
    { id : 26, city_id: 3, created_at: 1447831581186, name: 'Josh' },
    { id : 27, city_id: 3, created_at: 1448831581186, name: 'Aaron' },
    { id : 45, city_id: 3, created_at: 1449831581186, name: 'Gabriel' }
]
我需要的是这样的回应:

[
    { id : 1, city_id: 3, created_at: 1445831581186, name: 'Michael' },
    { id : 2, city_id: 3, created_at: 1446831581186, name: 'Jennifer' },
    { id : 3, city_id: 3, created_at: 1447831581186, name: 'Josh' },
    { id : 4, city_id: 3, created_at: 1448831581186, name: 'Aaron' },
    { id : 5, city_id: 3, created_at: 1449831581186, name: 'Gabriel' }
]
对于筛选的查询:

GET /api/cities/3/people?createdAfter=1447831581186

[
    { id : 4, city_id: 3, created_at: 1448831581186, name: 'Aaron' },
    { id : 5, city_id: 3, created_at: 1449831581186, name: 'Gabriel' }
]
我的意思是,json响应ID必须在“城市”域中重新排序

MySQL数据库上的ID必须仍然是原来的11、19、26、27和45,我不希望/需要这个“临时”ID持续存在,但如果需要,我可以有一个第二个“ID_IN_CITY”列。此外,如果我更改了“个人”的“城市”,则必须重新计算此辅助id

实现这一目标的最佳技术是什么

这个例子只是为了说明我的问题,我的目标是让我的系统的最终用户清楚地看到ID。当他们创建第一个项目时,他们将看到漂亮的ID 1,而不是ID 3455958。也没有告诉他们我的数据库有多大


谢谢

首先,让我问一个看似不必要的问题,但值得一提的是:

为什么您希望用户在首次创建用户时看到“1”很重要

这似乎是一个愚蠢的要求,甚至可能是一种代码味道

要回答您的问题,这是一种老式的黑客攻击,而不是JPA解决方案,但您可以在内存中保存一个ID映射,以映射到已显示的记录。例如,您可以将“Michael”记录的数据库ID存储在一个Map对象中,该对象以DB ID作为键,以显示的ID作为值。如果映射中不存在DB id,则添加它,增加请求id号

...
static Map<Long, Long> idGrid = new HashMap<Long, Long>();
long displayId = 1L;

//then insert
idGrid.put(databaseId, displayId++);

//remove
idGrid.remove(databaseId);

//get an id
Long displayId = idGrid.get(databaseId);

...
。。。
静态映射idGrid=newhashmap();
长显示ID=1L;
//然后插入
put(databaseId,displayId++);
//除去
删除(数据库ID);
//取得身份证
Long displayId=idGrid.get(databaseId);
...

这将允许您存储任何数据库ID,并向用户显示任何其他任意ID。

此ID的意义是:如果它没有持久化,则无法识别任何内容。所以它实际上不是一个ID。为什么不直接使用返回数组中每个人的索引呢?我不能使用数组索引,因为在过滤查询中,考虑到“城市”域,我会得到错误的ID。为了更好地解释这一点,我更新了我的问题。考虑第三个示例,在这里我有QuielScript“CealEdTestCouter”过滤器。如果我使用数组索引,在第三个示例中,我将得到有序的id1和id2。那不是我想要的。我希望它们在“子条件”中排序,那么您确实需要这个辅助ID才能持久化。我还是不明白重点。在所有人中识别一个人的ID也在同一城市的人中识别该人。
...
static Map<Long, Long> idGrid = new HashMap<Long, Long>();
long displayId = 1L;

//then insert
idGrid.put(databaseId, displayId++);

//remove
idGrid.remove(databaseId);

//get an id
Long displayId = idGrid.get(databaseId);

...