Search code examples
couchbasecouchbase-java-apicouchbase-java-client

NullPointerException when bucket.defaultCollection() is called Couchbase SDK3


Getting NullPointerException when trying the below code

public class SalesCouchbaseDao {

    @Resource
    private Cluster cluster;

    @Autowired
    @Qualifier("salesBucket")
    private Bucket bucket;

    private final Logger LOG = LoggerFactory.getLogger(SalesCouchbaseDao.class);

    private Collection collection = bucket.defaultCollection();

The NullPointerException is returned on this line

private Collection collection = bucket.defaultCollection();

As per the documentation, this is the way to get default Collection however, i am getting null pointer exception

This is the CouchbaseConfigClass

@Configuration
public class CouchbaseConfig {

    private static final Logger LOG = LoggerFactory.getLogger(CouchbaseConfig.class);

    @Autowired
    private CipherHelper cipherHelper;

    /** Common */
    @Value("${couchbase.cluster.host}")
    private String host;

    /** sales bucket */
    @Value("${couchbase.cluster.bucket.sales}")
    private String salesBucket;

    @Value("${couchbase.cluster.query.timeout}")
    private Long queryTimeout;
    @Value("${couchbase.cluster.view.timeout}")
    private Long viewTimeout;

    @Value("${couchbase.cluster.username}")
    private String clusterUserName;

    @Value("${couchbase.cluster.password}")
    private String clusterPassword;

    private static final long RECONNECT_DELAY = 60L;

    /**
     * couchbaseCluster.
     *
     * @throws BadPaddingException
     * @throws IllegalBlockSizeException
     * @throws NoSuchPaddingException
     * @throws NoSuchAlgorithmException
     * @throws InvalidKeyException
     */
    @Bean
    public Cluster couchbaseCluster() throws InvalidKeyException, NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, BadPaddingException {
        ClusterEnvironment clusterEnvironment = ClusterEnvironment
                .builder()
                .timeoutConfig(TimeoutConfig.builder()
                        .queryTimeout(Duration.ofMillis(TimeUnit.SECONDS.toMillis(queryTimeout)))
                        .viewTimeout(Duration.ofMillis(TimeUnit.SECONDS.toMillis(viewTimeout))))
                .build();

        return Cluster.connect(host, ClusterOptions
                .clusterOptions(clusterUserName.trim(), cipherHelper.decrypt(clusterPassword.trim()))
                .environment(clusterEnvironment));
    }

    @Bean
    @Qualifier(value = "salesBucket")
    public Bucket salesBucket(final Cluster couchbaseCluster) {
        return this.getBucket(couchbaseCluster,salesBucket);
    }

    private Bucket getBucket(final Cluster couchbaseCluster, final String bucketName) {
        Bucket bucket = couchbaseCluster.bucket(bucketName);
        bucket.waitUntilReady(Duration.ofSeconds(10));
        return bucket;
    }
}

The above is the couchbase configuration class. The CouchbaseConfig is in a separate module. I am using couchbase sdk 3

How can i fix this code ?


Solution

  • Field initializers are invoked before Spring auto-wiring happens. The NullPointerException happens because bucket is still null when the collection field is initialized.

    One option is to use a bean lifecycle callback to get the collection after the bucket has been auto-wired:

    private Collection collection;
    
    @PostConstruct
    private void initCollection() {
        this.collection = bucket.defaultCollection();
    }
    

    Another option would be to treat the collection as a bean, and auto-wire the collection instead of the bucket.

    A third option would be to use constructor injection or setter injection, passing the bucket to the constructor or setter, and initializing the collection inside the constructor/setter. Refer to spring @Autowire property vs setter.