Я хотел бы сохранить новый объект, используя HazlecastRepository. Когда идентификатор равен нулю, KeyValueTemplate использует SecureRandom и генерирует идентификатор, например -123123123123123123.
Я не хочу сохранять идентификатор таким образом, вместо этого я хотел бы получить его из последовательности в БД и положить его на карту.
Я нашел 2 решения:
1) В AdminService получить следующее значение из последовательности в базе данных и установить его
2) Создать атом c идентификатор счетчика на сервере Hazelcast и инициализация его с текущим значением из последовательности. В AdminService получить счетчик, увеличить значение и установить идентификатор.
но они не очень красивые.
У вас есть другие идеи?
Код:
@Configuration
@EnableHazelcastRepositories(basePackages = "com.test")
public class HazelcastConfig {
@Bean
public HazelcastInstance hazelcastInstance(ClientConfig clientConfig) {
return HazelcastClient.newHazelcastClient(clientConfig);
}
@Bean
@Qualifier("client")
public ClientConfig clientConfig() {
ClientConfig clientConfig = new ClientConfig();
clientConfig.setClassLoader(HazelcastConfig.class.getClassLoader());
ClientNetworkConfig networkConfig = clientConfig.getNetworkConfig();
networkConfig.addAddress("127.0.0.1:5701");
networkConfig.setConnectionAttemptLimit(20);
return clientConfig;
}
@Bean
public KeyValueTemplate keyValueTemplate(ClientConfig clientConfig) {
return new KeyValueTemplate(new HazelcastKeyValueAdapter(hazelcastInstance(clientConfig)));
}
}
@Service
@RequiredArgsConstructor
public class AdminService {
private final UserRepository userRepository;
...
@Transactional
public User addOrUpdateUser(UserUpdateDto dto) {
validate(dto);
User user = dto.getId() != null ? userService.getUser(dto.getId()) : new User();
mapUser(user, dto);
return userRepository.save(user);
}
...
}
@Repository
public interface UserRepository extends HazelcastRepository<User, Long> {
}
@KeySpace("users")
@Entity
@Table(name = "users)
@Data
@AllArgsConstructor
@NoArgsConstructor
public class User extends DateAudit implements Serializable {
@javax.persistence.Id
@org.springframework.data.annotation.Id
// @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "user_generator")
// @SequenceGenerator(name="user_generator", sequenceName = "user_seq")
private Long id;
...
}
Сервер Hazelcast:
@Component
@Slf4j
public class UserLoader implements ApplicationContextAware, MapStore<Long, User> {
private static UserJpaRepository userJpaRepository;
@Override
public User load(Long key) {
log.info("load({})", key);
return userJpaRepository.findById(key).orElse(null);
}
@Override
public Map<Long, User> loadAll(Collection<Long> keys) {
Map<Long, User> result = new HashMap<>();
for (Long key : keys) {
User User = this.load(key);
if (User != null) {
result.put(key, User);
}
}
return result;
}
@Override
public Iterable<Long> loadAllKeys() {
return userJpaRepository.findAllId();
}
@Override
public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
userJpaRepository = applicationContext.getBean(UserJpaRepository.class);
}
@Override
public void store(Long aLong, User user) {
userJpaRepository.save(user);
}
@Override
public void storeAll(Map<Long, User> map) {
for (Map.Entry<Long, User> mapEntry : map.entrySet()) {
store(mapEntry.getKey(), mapEntry.getValue());
}
}
@Override
public void delete(Long aLong) {
userJpaRepository.deleteById(aLong);
}
@Override
public void deleteAll(Collection<Long> collection) {
collection.forEach(this::delete);
}
}
public interface UserJpaRepository extends CrudRepository<User, Long> {
@Query("SELECT u.id FROM User u")
Iterable<Long> findAllId();
}