HazelcastRepository-如何保存新实体(具有序列中的ID)并将其放入地图中

问题描述 投票:0回答:1

我想使用HazlecastRepository保存一个新实体。当id为null时,KeyValueTemplate使用SecureRandom并生成类似于-123123123123123123的id。

我不想这样保存id,相反,我想从db的序列中获取它并将其放入地图。

我找到2个解决方案:

1)在AdminService中,从数据库序列中获取下一个值并进行设置

2)在Hazelcast服务器中创建原子计数器ID,并使用序列中的当前值对其进行初始化。在AdminService中,获取计数器,增加值并设置ID。

但是它们不是很漂亮。

您还有其他想法吗?

代码:

@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();
}
spring-boot hazelcast
1个回答
0
投票

我认为没有比您描述的更好的方法了。

我会选择第二种解决方案,因为那样的话,您至少只与Hazelcast服务器耦合。

© www.soinside.com 2019 - 2024. All rights reserved.