I wrote a controller that must return an unique String. The requirement is that two calling of this controller never return the same String, even after years and even if the code will scale to more VMs.
My question is if the following code is correct to achieve to declared purpose, or if you have any hint.
Controller:
@RestController
public class UtilityController {
@Autowired
UtilityServices utilityServices;
@GetMapping("/uniqueIdentifier")
@ResponseBody
public String uniqueIdentifier() {
return utilityServices.getUniqueIdentifier();
}
Service:
@Service
public class UtilityServices {
@Autowired
private UniqueIdRepository uniqueIdRepository;
@Transactional
public String getUniqueIdentifier() {
String uniqueId = RandomString.getSecureRandomString();
while (uniqueIdRepository.existsById(uniqueId)) {
uniqueId = RandomString.getSecureRandomString();
}
uniqueIdRepository.save(new UniqueId(uniqueId));
return uniqueId;
}
}
Entity:
@Entity
@AllArgsConstructor
@NoArgsConstructor
@Getter
@Setter
@EqualsAndHashCode
@ToString
public class UniqueId implements Serializable {
@Id
private String uniqueId;
}
Repository:
public interface UniqueIdRepository extends CrudRepository<UniqueId, String> {
}
That's all. I omit the code the RandomString
class because it's not relevant in this context: I wrote a code based on SecureRandom
, it is very likely that each time it returns a different String, but I have no guarantees about it. Let's assume that sooner or later my RandomString.getSecureRandomString()
method can return the same String.
I'm not sure if the @Transactional
annotation guarantees that the getUniqueIdentifier()
method never throws an error.