Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/378.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 测试具有列表属性的Bean时出现问题_Java_Spring Boot_Jpa - Fatal编程技术网

Java 测试具有列表属性的Bean时出现问题

Java 测试具有列表属性的Bean时出现问题,java,spring-boot,jpa,Java,Spring Boot,Jpa,大家好,这是我的项目: 通过@OneToMany关系相互连接的两个实体: @Entity public class Brand { @Id @GeneratedValue private Long id; @Column @NotNull(message = "Brand can not have empty name.") private String name; @Column private String descrip

大家好,这是我的项目:

通过
@OneToMany
关系相互连接的两个实体:

@Entity
public class Brand {

    @Id
    @GeneratedValue
    private Long id;

    @Column
    @NotNull(message = "Brand can not have empty name.")
    private String name;

    @Column
    private String description;

    @OneToMany(mappedBy="brand"
    , cascade= {CascadeType.DETACH,
            CascadeType.MERGE,
            CascadeType.PERSIST,
            CascadeType.REFRESH},
    fetch = FetchType.EAGER)    
    @OrderBy("price ASC") // order products by price
    private List<Product> productList;

    // getters and setter following here ...
}

@Entity
public class Product {

    @Id
    @GeneratedValue
    private Long id;

    @Column
    @NotNull(message = "Product can not have empty name.")
    private String name;

    @Column
    private Double price;

    @Column
    private Boolean onSale=false;

    @ManyToOne(cascade= {CascadeType.DETACH,
            CascadeType.MERGE,
            CascadeType.PERSIST,
            CascadeType.REFRESH})
    @JoinColumn(name="brand_id", nullable=false)
    private Brand brand;

 // getters and setter following here ...
}

package com.microservices.product.datatranferobject;

import com.fasterxml.jackson.annotation.JsonIgnore;
import com.fasterxml.jackson.annotation.JsonInclude;


@JsonInclude(JsonInclude.Include.NON_NULL)
public class ProductDTO {

    private Long id;

    private String name;    

    private Double price;   

    @JsonIgnore // omit this property when exposing data over the API
    private Boolean onSale;

    private String event;

    public ProductDTO() {

    }    

    public ProductDTO(Long id, String name, Double price, String event, Boolean onSale) {
        super();
        this.id = id;
        this.name = name;
        this.price = price;
        this.event = event;
        this.onSale=onSale;
    }

    public Boolean getOnSale() {
        return onSale;
    }

    public void setOnSale(Boolean onSale) {
        this.onSale = onSale;
    }

    public Long getId() {
        return id;
    }

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

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Double getPrice() {
        return price;
    }

    public void setPrice(Double price) {
        this.price = price;
    }

    public String getEvent() {
        return onSale?"ON SALE":null;
    }

    public void setEvent(String event) {
        this.event = event;
    }    

}


public class BrandDTO {
    private String name;

    private List<ProductDTO> productList;

    public BrandDTO() {}

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<ProductDTO> getProductList() {
        return productList;
    }

    public void setProductList(List<ProductDTO> productList) {
        this.productList = productList;
    }   
}

我在这里做错什么了吗?为什么我的列表中没有填写我的实体,而是填写了LinkedHashMaps?是否有解决方案来获取产品列表?

编辑:

我还在这里提供了我的项目依赖项,并在我的帖子顶部添加了DTO:

buildscript {
    ext {
        springBootVersion = '2.1.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.microservices'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation('org.springframework.boot:spring-boot-starter-web')
    compile("org.springframework.boot:spring-boot-devtools")
    compile group: 'org.modelmapper', name: 'modelmapper', version: '2.1.0'
    runtimeOnly('com.h2database:h2')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
    testImplementation 'org.assertj:assertj-core:3.15.0'
    compile group: 'com.google.guava', name: 'guava', version: '23.5-jre'
    compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.7.0'
    compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.7.0' 
}


问题是
TreeMap
的参数化不能从
TreeMap.class
内部
restemplate.getForObject(…)

您需要使用更通用的版本:

restTemplate.exchange(
    "http://localhost:"+port+"/v1/search/get/products/",
    HttpMethod.GET,
    new HttpEntity<>(null, headers),
    new ParameterizedTypeReference<TreeMap<String, List<ProductDTO>>() {}
)
restemplate.exchange(
"http://localhost:“+port+”/v1/search/get/products/”,
HttpMethod.GET,
新的HttpEntity(空,标题),

新参数化类型引用可以将产品粘贴到(即使是相同的)还有pom.xml?我问这个问题是因为我的代码是hi@Adam我刚刚做的,你的意思是你测试了相同的代码,没有抛出任何错误?我刚刚根据你粘贴的代码创建了一个项目,它正在工作。为了100%确定我们有相同的代码库,你能把你的代码推到github,这样我就可以克隆它吗?尝试更改
TreeMap productList=restTemplate.getForObject(“http://localhost:“+port+”/v1/search/get/products/”,TreeMap.class);
to
TreeMap productList=restemplate.getForObject(”http://localhost:“+port+”/v1/search/get/products/”,TreeMap.class)在运行时,它不能推断您期望的是一个
列表
。我打赌这是可行的。问题是您希望表现得像键不重要一样,只有值才重要。Jackson不知道如何做。因此,要么做一个自定义反序列化器,要么显式键入键。
public class ModelMapper {
    public static BrandDTO makeBrandDTO(Brand myBrand)
    {
        BrandDTO myBrandDTO=new BrandDTO();

        org.modelmapper.ModelMapper myStandardMapper=new org.modelmapper.ModelMapper();

        List<ProductDTO> myProductsList=myBrand.getProductList()
                .stream()
                .map(product->myStandardMapper.map(product, ProductDTO.class))
                .collect(Collectors.toList());
        myBrandDTO.setProductList(myProductsList);

        myBrandDTO.setName(myBrand.getName());

        return myBrandDTO;
    }
}


@RestController
@RequestMapping("v1/search")
public class BrandController {

    @Autowired
    BrandService myBrandService;

    @GetMapping("/get/products/")
    public Map<String, List<ProductDTO>> getAllProductsMap(){

        List<BrandDTO> myList= myBrandService.getAllBrands()
        .stream().map(brand->ModelMapper.makeBrandDTO(brand))
        .collect(Collectors.toList());      

        Map<String, List<ProductDTO>> myMap=new TreeMap<String, List<ProductDTO>> ();

        myList.forEach(brand->myMap.put(brand.getName(), brand.getProductList()));

        return myMap;
    }

}

@RunWith(SpringRunner.class)
@SpringBootTest(classes = ProductApplication.class,webEnvironment=WebEnvironment.RANDOM_PORT)
public class ControllerLayerTester {

    private static Log myLogger = LogFactory.getLog(ControllerLayerTester.class);

    private static RestTemplate restTemplate;

    private static HttpHeaders headers;

    @LocalServerPort
    private int port;

    @BeforeClass
    public static void runBeforeAllTestMethods() {

        restTemplate = new RestTemplate();
        headers = new HttpHeaders();
        headers.setContentType(MediaType.APPLICATION_JSON);

    }

    /**
     * simple test to verify the given requirements
     */
    @Test
    public void testBrandListIsOrdered() {

        TreeMap<String, List<ProductDTO>> productList=restTemplate.getForObject("http://localhost:"+port+"/v1/search/get/products/",TreeMap.class);

        for (List<ProductDTO> myProductList:productList.values()) {

            myProductList.forEach(product->assertTrue(product.getId()!=null));

        }
    }

}
java.lang.ClassCastException: java.util.LinkedHashMap cannot be cast to com.microservices.product.datatranferobject.ProductDTO
    at java.util.ArrayList.forEach(ArrayList.java:1257)
    at com.microservices.product.ControllerLayerTester.testBrandListIsOrdered(ControllerLayerTester.java:81)
buildscript {
    ext {
        springBootVersion = '2.1.0.RELEASE'
    }
    repositories {
        mavenCentral()
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
    }
}

apply plugin: 'java'
apply plugin: 'eclipse'
apply plugin: 'org.springframework.boot'
apply plugin: 'io.spring.dependency-management'

group = 'com.microservices'
version = '0.0.1-SNAPSHOT'
sourceCompatibility = 1.8

repositories {
    mavenCentral()
}


dependencies {
    implementation('org.springframework.boot:spring-boot-starter-data-jpa')
    implementation('org.springframework.boot:spring-boot-starter-web')
    compile("org.springframework.boot:spring-boot-devtools")
    compile group: 'org.modelmapper', name: 'modelmapper', version: '2.1.0'
    runtimeOnly('com.h2database:h2')
    testImplementation('org.springframework.boot:spring-boot-starter-test')
    testImplementation 'org.assertj:assertj-core:3.15.0'
    compile group: 'com.google.guava', name: 'guava', version: '23.5-jre'
    compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.7.0'
    compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.7.0' 
}

restTemplate.exchange(
    "http://localhost:"+port+"/v1/search/get/products/",
    HttpMethod.GET,
    new HttpEntity<>(null, headers),
    new ParameterizedTypeReference<TreeMap<String, List<ProductDTO>>() {}
)