HazelcastRepository - как сохранить новый объект (с идентификатором из последовательности) и поместить его на карту - PullRequest
0 голосов
/ 10 марта 2020

Я хотел бы сохранить новый объект, используя 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();
}

1 Ответ

0 голосов
/ 12 марта 2020

Я думаю, что нет лучшего способа, чем вы описали.

Я бы go со вторым решением, потому что тогда вы по крайней мере связаны только с сервером Hazelcast.

...