简体   繁体   中英

Secondary ID for JPA entity by group

Let's suppose there are 2 JPA entities:

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;
}

And there are 10 "City" objects with 5 different "Person" in each of them, that makes a total of 50 items in "Person" table, randomly generated.

Now i want to list "Person" objects from "City" ID 3 by querying a rest end point:

GET /api/cities/3/people

Let's suppose response from the rest api controller is:

[
    { 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' }
]

what i need is response to be like:

[
    { 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' }
]

and for a filtered query:

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' }
]

i mean, the json response ids must be reordered within "City" domain.

The ID's on the MySQL database must still be the original ones 11, 19, 26, 27 and 45, i don't want / need this "temporary" id to persist, but i can have a secondary "ID_IN_CITY" column if needed. Also, if i change the "City" of a "Person" this secondary id must be recalculated.

What's the best technique to achieve this ?

This example was just to illustrate my problem, my goal is to make ids clean to the end user of my system. When they create the first item, they'll see beautiful ID 1, and not ID 3455958. Also not giving them a clue of how large is my database.

Thanks

First, let me ask a question that may seem unnecessary, but bears asking:

Why does it matter that you want the user to see "1" when they first create a user?

This seems like a silly requirement and possibly even a code smell.

To answer your question, it's old-school hack and not a JPA solution, but you could hold a Map of ids in memory to map to the records that have been displayed. So for instance you would store the database ID for the 'Michael' record in an Map object that had the DB id as a key and the displayed id as a value. If the DB id does not exist in the Map, then add it, incrementing the request ID number.

...
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);

...

This would allow you to store any database ID, and display any other arbitrary ID to the user.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM