Is your feature request related to a problem? Please describe.

JacksonRecordConstructorExample.java.zip

I need to deserialize an object that has two constructors, a single-arg version that takes a java record, and a no-arg version. Depending on the provided JSON, I want Jackson to auto-detect which one to use.

Jackson never auto-detects the constructor that takes a record. Using @JsonCreator is not a good choice, because then it always uses the single-arg constructor instead of the no-arg.

Describe the solution you'd like

Jackson does auto-detect a version that has @JsonProperties for each parameter, like this: public JacksonRecordConstructorExample( @JsonProperty("a") int a, @JsonProperty("b") int b, @JsonProperty("c") int c )

It seems to me that it ought to treat this constructor version equivalently and auto-detect it: public record Triple( int a, int b, int c ) {}

public JacksonRecordConstructorExample( Triple triple )

Usage example

See attached test case

Additional context

I'm using Jackson 2.19.1

No response

Comment From: jessebarnum

btw your reporting feature does not allow uploads of .java files, which is why I had to zip my file

Comment From: pjfanning

Can you just put the code in a comment? Accepting zip files from strangers is a security risk. Or create a GitHub project and link it.

Comment From: jessebarnum

OK, here's the text case:

package com.prosc.workflows;

import com.fasterxml.jackson.annotation.JsonCreator;
import com.fasterxml.jackson.annotation.JsonProperty;
import com.fasterxml.jackson.databind.DeserializationFeature;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.junit.jupiter.api.Assertions;

/**
 * Created by IntelliJ IDEA.
 * User: jesse
 * Date: 7/12/25
 */
public class JacksonRecordConstructorExample {
    public record Triple( int a, int b, int c ) {}

    private Triple triple;

    // Test passes with this three-arg constructor
    /*public JacksonRecordConstructorExample( @JsonProperty("a") int a, @JsonProperty("b") int b, @JsonProperty("c") int c ) {
        System.out.println( "Three-arg constructor called" );
        this.triple = new Triple( a, b, c );
    }*/

    //It seems like Jackson should treat this record constructor as equivalent to the three-arg version. Is there some annotation I can use to make Jackson treat it that way?
    //@JsonCreator //This makes my test pass, but it's not a good solution because I have other cases where the no-arg constructor must be used
    public JacksonRecordConstructorExample( Triple triple ) {
        System.out.println( "One-arg constructor called" );
        this.triple = triple;
    }

    public JacksonRecordConstructorExample() {
        triple = null;
    }





    public static void main( String[] args ) throws Exception {
        String jsonExample1 = """
                { "a": 1, "b": 2, "c": 3 }""";

        final JacksonRecordConstructorExample example1 = new ObjectMapper().configure( DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false ).readValue( jsonExample1, JacksonRecordConstructorExample.class );
        Assertions.assertNotNull( example1.triple );
    }
}

Comment From: JooHyukKim

Can you first try annotating the no-arg constructor also?

Jackson never auto-detects the constructor that takes a record. Using @JsonCreator is not a good choice, because then it always uses the single-arg constructor instead of the no-arg.

Btw, what is the intention behind your statement @jessebarnum ?

And this note also, regarding one-arg constructor might help.