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.