Partial update is different from full-resource update and we should implement it in a different way. Let's create two request POJO classes. One class will be used to create and update resources, second will be used to partially update given resource. To emphasise it we will use different HTTP methods.  To distinguish null from absence we can use java.util.Optional class.
- SampleCompleteRequestclass we use together with- POST(create) and- PUT(update) methods.
- SamplePartialRequestclass we use together with- PATCH(partially update) method.
To avoid boilerplate code in this example I'm using Lombok and MapStruct but it is not required.
Model
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
@Data
public class SampleCompleteRequest {
    @NotBlank
    private String name;
    private String value;
}
import jakarta.validation.constraints.NotBlank;
import lombok.Data;
import java.util.Optional;
@Data
public class SamplePartialRequest {
    private Optional<@NotBlank String> name;
    private Optional<String> value;
}
import lombok.Data;
@Data
public class SampleResponse {
    private Long id;
    private String name;
    private String value;
}
import lombok.Data;
@Data
public class Sample {
    //@Id - Hibernate annotations are removed
    private Long id;
    private String name;
    private String value;
}
MapStruct
In MapStruct we need to define an interface with all methods we need.
import com.example.demo.model.SampleCompleteRequest;
import com.example.demo.model.SamplePartialRequest;
import com.example.demo.model.SampleResponse;
import jakarta.annotation.Nullable;
import org.mapstruct.BeanMapping;
import org.mapstruct.Mapper;
import org.mapstruct.MappingTarget;
import org.mapstruct.ReportingPolicy;
import java.util.Optional;
import static org.mapstruct.MappingConstants.ComponentModel.SPRING;
import static org.mapstruct.NullValueCheckStrategy.ALWAYS;
import static org.mapstruct.NullValuePropertyMappingStrategy.IGNORE;
@Mapper(unmappedTargetPolicy = ReportingPolicy.IGNORE, componentModel = SPRING)
public interface SamplesMapper {
    @BeanMapping(nullValueCheckStrategy = ALWAYS, nullValuePropertyMappingStrategy = IGNORE)
    Sample patch(SamplePartialRequest input, @MappingTarget Sample target);
    Sample update(SampleCompleteRequest input, @MappingTarget Sample target);
    SampleResponse mapToResponse(Sample input);
    default String optionalToString(@Nullable Optional<String> nullable) {
        return nullable == null ? null : nullable.orElse(null);
    }
}
Plugin will generate boilerplate code for us. Below class is autogenerated and we do not need to implement it manually.
@Component
public class SamplesMapperImpl implements SamplesMapper {
    @Override
    public Sample patch(SamplePartialRequest input, Sample target) {
        if ( input == null ) {
            return target;
        }
        if ( input.getName() != null ) {
            target.setName( optionalToString( input.getName() ) );
        }
        if ( input.getValue() != null ) {
            target.setValue( optionalToString( input.getValue() ) );
        }
        return target;
    }
    @Override
    public Sample update(SampleCompleteRequest input, Sample target) {
        if ( input == null ) {
            return target;
        }
        target.setName( input.getName() );
        target.setValue( input.getValue() );
        return target;
    }
    @Override
    public SampleResponse mapToResponse(Sample input) {
        if ( input == null ) {
            return null;
        }
        SampleResponse sampleResponse = new SampleResponse();
        sampleResponse.setId( input.getId() );
        sampleResponse.setName( input.getName() );
        sampleResponse.setValue( input.getValue() );
        return sampleResponse;
    }
}
Resource
A controller class is easy to implement:
import com.example.demo.model.SampleCompleteRequest;
import com.example.demo.model.SamplePartialRequest;
import com.example.demo.model.SampleResponse;
import com.example.service.SamplesMapper;
import com.example.service.SamplesService;
import jakarta.validation.Valid;
import lombok.AllArgsConstructor;
import org.springframework.hateoas.CollectionModel;
import org.springframework.hateoas.EntityModel;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PatchMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.PutMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@AllArgsConstructor
@RestController
@RequestMapping(value = "/api/v1/samples")
public class SamplesResource {
    private final SamplesMapper mapper;
    private final SamplesService samplesService;
    @GetMapping
    public CollectionModel<SampleResponse> listAll() {
        List<SampleResponse> entities = samplesService.list().stream().map(mapper::mapToResponse).toList();
        return CollectionModel.of(entities);
    }
    @PostMapping
    public EntityModel<SampleResponse> addSample(@Valid @RequestBody SampleCompleteRequest request) {
        var entity = samplesService.create(request);
        var response = mapper.mapToResponse(entity);
        return EntityModel.of(response);
    }
    @PutMapping(path = "{id}")
    public EntityModel<SampleResponse> updateSample(@PathVariable Long id, @Valid @RequestBody SampleCompleteRequest request) {
        var entity = samplesService.update(id, request);
        var response = mapper.mapToResponse(entity);
        return EntityModel.of(response);
    }
    @PatchMapping(path = "{id}")
    public EntityModel<SampleResponse> partiallyUpdateSample(@PathVariable Long id, @Valid @RequestBody SamplePartialRequest request) {
        var entity = samplesService.patch(id, request);
        var response = mapper.mapToResponse(entity);
        return EntityModel.of(response);
    }
}
A service class is also straightforward:
import com.example.demo.model.SampleCompleteRequest;
import com.example.demo.model.SamplePartialRequest;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Service;
import java.util.List;
@Service
@AllArgsConstructor
public class SamplesService {
    private final SamplesMapper mapper;
    private final SamplesRepository repository;
    public List<Sample> list() {
        return repository.listAll();
    }
    public Sample create(SampleCompleteRequest request) {
        var sample = mapper.update(request, new Sample());
        return repository.save(sample);
    }
    public Sample update(Long id, SampleCompleteRequest request) {
        var sample = repository.find(id).orElseThrow();
        mapper.update(request, sample);
        return repository.save(sample);
    }
    public Sample patch(Long id, SamplePartialRequest request) {
        var sample = repository.find(id).orElseThrow();
        mapper.patch(request, sample);
        return repository.save(sample);
    }
}
See also:
- HTTP PUT vs HTTP PATCH in a REST API
- Difference between Jackson objectMapper to others
- Spring MVC PATCH method: partial updates