如何解决不可变类中的“无法使用带参数的构造函数NO_CONSTRUCTOR实例化'className'”

时间:2019-04-24 10:14:49

标签: java spring mongodb

我在春季启动时使用MongoDBRepository,当我在数据库中保存一些对象时一切正常。但是当我通过id查找对象时spring不允许这样做。

我尝试将VehicleRoutingProblemSolution类型更改为Object类型,但是VehicleRoutingProblemSolution具有其他对象字段PickupService,并且没有默认构造函数。是的,此类具有不可变的...我无法创建默认构造函数,该怎么办?

import com.fasterxml.jackson.annotation.JsonProperty;
import com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution;
import org.springframework.data.annotation.Id;
import org.springframework.data.mongodb.core.mapping.Document;

@Document(collection = "vrp_solutions")
public class VrpSolutionHolder {
    // Specifies the solution id
    @Id
    @JsonProperty("id")
    private String id;

    // Specifies the solution id
    @JsonProperty("solution")
    private VehicleRoutingProblemSolution vehicleRoutingProblemSolution;

    // Created at timestamp in millis
    @JsonProperty("created_at")
    private Long created_at = System.currentTimeMillis();


    public VrpSolutionHolder(String id, VehicleRoutingProblemSolution vehicleRoutingProblemSolution) {
        this.id = id;
        this.vehicleRoutingProblemSolution = vehicleRoutingProblemSolution;
    }

    public String getId() {
        return id;
    }

    public void setId(String id) {
        this.id = id;
    }

    public VehicleRoutingProblemSolution getVehicleRoutingProblemSolution() {
        return vehicleRoutingProblemSolution;
    }

    public void setVehicleRoutingProblemSolution(VehicleRoutingProblemSolution vehicleRoutingProblemSolution) {
        this.vehicleRoutingProblemSolution = vehicleRoutingProblemSolution;
    }

    public Long getCreated_at() {
        return created_at;
    }

    public void setCreated_at(Long created_at) {
        this.created_at = created_at;
    }
}

  

org.springframework.web.util.NestedServletException:请求   处理失败;嵌套异常为   org.springframework.data.mapping.model.MappingInstantiationException:   无法实例化   com.graphhopper.jsprit.core.problem.solution.VehicleRoutingProblemSolution   使用带有参数的构造函数NO_CONSTRUCTOR

2 个答案:

答案 0 :(得分:1)

我遇到了完全相同的问题。包含其他类实例的持久性不变类,当通过此存储库方法检索时,抛出上述异常:

public interface ProjectCodeCacheRepository extends MongoRepository<CachedCode, String> { public CachedCode findByCode(String code);
public List<CachedCode> findByClientId(UUID clientId); } ... List<CachedCode> cachedForClient = this.codeCacheRepo.
findByClientId (clientId); ...

根据Erwin Smouts的提示,通过给它一个特殊的构造方法org.springframework.data.annotation.PersistenceConstructor进行了修正,可以很好地解决此问题:

@Document(collection="cachedcodes")
public class CachedCode {

@PersistenceConstructor
public CachedCode(String code, UUID clientId, LocalDateTime expiration) {
    this.code = code;
    this.clientId = clientId;
    this.expiration = expiration;
}

public CachedCode(String code, UUID clientId, long secondsExpiring) {
    this.code = code;
    this.clientId = clientId;
    this.expiration = LocalDateTime.now().plusSeconds(secondsExpiring);
}


public UUID getClientId( ) {
    return this.clientId;
}

public String getCode() {
    return this.code;
}

public boolean hasExpired(LocalDateTime now) {
    return (expiration.isBefore(now));
}

...
@Id
private final String code;
private final UUID clientId;
private final LocalDateTime expiration;

}`

因此,您应该检查VehicleRoutingProblemSolution是否具有a)匹配数据库字段的构造函数(在mongo客户端中签入)和b)注释为驱动程序使用的构造函数(或引擎盖下的任何Spring魔术块) )。

答案 1 :(得分:0)

如果您的框架工具 需要 (可见)无参数构造函数(以及随附的设置器),并且您拥有的类是 必需 保持原样,那么您可以滚动自己的帐户,例如MutableVehicleRoutingProblemSolution,在设置员的位置:

this.vehicleRoutingProblemSolution = new VehicleRoutingProblemSolution(vehicleRoutingProblemSolution.getId(), newSolution);

因此,您的MutableVehicleRoutingProblemSolution会包裹现有的VehicleRoutingProblemSolution。

气味难闻,但符合要求。

(或者您可以尝试找到一种能够使用的工具,而不是包含字段上的注释,而是构造函数参数上的注释。)