Specify field is transient for MongoDB but not for RestController

As long as you use org.springframework.data.annotation.Transient it should work as expected. Jackson knows nothing about spring-data and it ignores it's annotations.

Sample code, that works:

interface PersonRepository extends CrudRepository<Person, String> {}
import org.springframework.data.annotation.Id;
import org.springframework.data.annotation.Transient;
import org.springframework.data.mongodb.core.mapping.Document;

@Document
class Person {
    @Id
    private String id;
    private String name;
    @Transient
    private Integer age;

    // setters & getters & toString()
}
@RestController
@RequestMapping("/person")
class PersonController {
    private static final Logger LOG = LoggerFactory.getLogger(PersonController.class);
    private final PersonRepository personRepository;

    @Autowired
    PersonController(PersonRepository personRepository) {
        this.personRepository = personRepository;
    }

    @RequestMapping(method = RequestMethod.POST)
    public void post(@RequestBody Person person) {
        // logging to show that json deserialization works
        LOG.info("Saving person: {}", person);
        personRepository.save(person);
    }

    @RequestMapping(method = RequestMethod.GET)
    public Iterable<Person> list() {
        Iterable<Person> list = personRepository.findAll();
        // setting age to show that json serialization works
        list.forEach(foobar -> foobar.setAge(18));

        return list;
    }
}

Executing POST http://localhost:8080/person:

{
    "name":"John Doe",
    "age": 40
}
  • Log output Saving person: Person{age=40, id='null', name='John Doe'}
  • Entry in person collection: { "_id" : ObjectId("55886dae5ca42c52f22a9af3"), "_class" : "demo.Person", "name" : "John Doe" } - age is not persisted

Executing GET http://localhost:8080/person:

  • Result: [{"id":"55886dae5ca42c52f22a9af3","name":"John Doe","age":18}]

I solved by using @JsonSerialize. Optionally you can also opt for @JsonDeserialize if you want this to be deserailized as well.

@Entity
public class Article {

@Column(name = "title")
private String title;

@Transient
@JsonSerialize
@JsonDeserialize
private Boolean testing;
}

// No annotations needed here
public Boolean getTesting() {
    return testing;
}

public void setTesting(Boolean testing) {
    this.testing = testing;
}

The problem for you seems to be that both mongo and jackson are behaving as expected. Mongo does not persist the data and jackson ignores the property since it is marked as transient. I managed to get this working by 'tricking' jackson to ignore the transient field and then annotating the getter method with @JsonProperty. Here is my sample bean.

    @Entity
    public class User {

    @Id
    private Integer id;
    @Column
    private String username;

    @JsonIgnore
    @Transient
    private String password;

    @JsonProperty("password")
    public String getPassword() {
        return // your logic here;
    }
}

This is more of a work around than a proper solution so I am not sure if this will introduce any side effects for you.