简体   繁体   中英

Can't get the JPA entity ID in the JSON output

We are trying a POC with Spring-Data-JPA and Spring-Data-Rest. The output looks as excepted, we have the values of our entity fields except for the id, the id field is set in an Abstract class.

We are using a simple entity witch extends of AbstractPersistable (it's a spring-data-jpa class http://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/domain/AbstractPersistable.html ).

Here the source code of this one:

@MappedSuperclass
public abstract class AbstractPersistable<PK extends Serializable> implements Persistable<PK> {

    private static final long serialVersionUID = -5554308939380869754L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "ID")
    private PK id;

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Persistable#getId()
     */
    public PK getId() {

        return id;
    }

    /**
     * Sets the id of the entity.
     * 
     * @param id the id to set
     */
    protected void setId(final PK id) {

        this.id = id;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Persistable#isNew()
     */
    public boolean isNew() {

        return null == getId();
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#toString()
     */
    @Override
    public String toString() {

        return String.format("Entity of type %s with id: %s", this.getClass().getName(), getId());
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#equals(java.lang.Object)
     */
    @Override
    public boolean equals(Object obj) {

        if (null == obj) {
            return false;
        }

        if (this == obj) {
            return true;
        }

        if (!getClass().equals(obj.getClass())) {
            return false;
        }

        AbstractPersistable<?> that = (AbstractPersistable<?>) obj;

        return null == this.getId() ? false : this.getId().equals(that.getId());
    }

    /*
     * (non-Javadoc)
     * 
     * @see java.lang.Object#hashCode()
     */
    @Override
    public int hashCode() {

        int hashCode = 17;

        hashCode += null == getId() ? 0 : getId().hashCode() * 31;

        return hashCode;
    }
}

and our entity:

@Entity
@Table(name = "TEST_ENTITY")
public class TestEntity extends AbstractPersistable<Long> {

    @Column(name = "TITLE", nullable = false, length = 100)
    private String title;

    @Column(name = "DESCRIPTION", length = 500)
    private String description;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "GLOBAL_DATATYPE_ID", referencedColumnName = "ID", nullable = false, updatable = false)
    private GlobalDataType dataType;

    @Enumerated(EnumType.STRING)
    @Column(name = "VALUE_TYPE", nullable = false, length = 30)
    private ValueType valueType;

    @Enumerated(EnumType.STRING)
    @Column(name = "ATTRIBUTE_TYPE", nullable = false, length = 30)
    private AttributeType attributeType;

    @Column(name = "FE_DISPLAY")
    @Convert(converter=BooleanTFConverter.class)
    private Boolean feDisplay;

 {... getter setter equals hashcode toString ...}
}

then the the service (using spring-data-rest):

@RepositoryRestResource(path = "test")
public interface TestEntityRepository extends JpaRepository<TestEntity, Long> {
}

We run the app with Spring boot And the output on Chrome (URL is http://localhost:8080/test ) is a JSON + HAL data (the id is not displayed !!!):

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/test{?page,size,sort}",
      "templated" : true
    }
  },
  "_embedded" : {
    "testEntities" : [ {
      "title" : "Test",
      "description" : "TEST",
      "valueType" : "SINGLE",
      "attributeType" : "ATTRIBUTE",
      "feDisplay" : true,
      "new" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/test/1"
        },
        "dataType" : {
          "href" : "http://localhost:8080/test/1/dataType"
        }
      }
    } ]
  },
  "page" : {
    "size" : 20,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}

And another thing is when we use AbstractAuditable on the TestEntity ( http://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/domain/AbstractAuditable.html ), it works, we get the fields values from AbstractAuditable but we still don't get the id...

@Entity
@Table(name = "TEST_ENTITY")
public class TestEntity  extends AbstractAuditable<User, Long> {
...
}

@MappedSuperclass
public abstract class AbstractAuditable<U, PK extends Serializable> extends AbstractPersistable<PK> implements
        Auditable<U, PK> {

    private static final long serialVersionUID = 141481953116476081L;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "CREATED_BY", referencedColumnName = "ID", nullable = false, updatable = false)
    private U createdBy;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "CREATED_DATE")
    private Date createdDate;

    @ManyToOne(fetch = FetchType.LAZY, optional = false)
    @JoinColumn(name = "LAST_MODIFIED_BY", referencedColumnName = "ID", nullable = false, updatable = false)
    private U lastModifiedBy;

    @Temporal(TemporalType.TIMESTAMP)
    @Column(name = "LAST_MODIFIED_DATE")
    private Date lastModifiedDate;

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Auditable#getCreatedBy()
     */
    public U getCreatedBy() {

        return createdBy;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.springframework.data.domain.Auditable#setCreatedBy(java.lang.Object)
     */
    public void setCreatedBy(final U createdBy) {

        this.createdBy = createdBy;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Auditable#getCreatedDate()
     */
    public DateTime getCreatedDate() {

        return null == createdDate ? null : new DateTime(createdDate);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.springframework.data.domain.Auditable#setCreatedDate(org.joda.time
     * .DateTime)
     */
    public void setCreatedDate(final DateTime createdDate) {

        this.createdDate = null == createdDate ? null : createdDate.toDate();
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Auditable#getLastModifiedBy()
     */
    public U getLastModifiedBy() {

        return lastModifiedBy;
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.springframework.data.domain.Auditable#setLastModifiedBy(java.lang
     * .Object)
     */
    public void setLastModifiedBy(final U lastModifiedBy) {

        this.lastModifiedBy = lastModifiedBy;
    }

    /*
     * (non-Javadoc)
     * 
     * @see org.springframework.data.domain.Auditable#getLastModifiedDate()
     */
    public DateTime getLastModifiedDate() {

        return null == lastModifiedDate ? null : new DateTime(lastModifiedDate);
    }

    /*
     * (non-Javadoc)
     * 
     * @see
     * org.springframework.data.domain.Auditable#setLastModifiedDate(org.joda
     * .time.DateTime)
     */
    public void setLastModifiedDate(final DateTime lastModifiedDate) {

        this.lastModifiedDate = null == lastModifiedDate ? null : lastModifiedDate.toDate();
    }
}

And JSON+HAL result:

{
  "_links" : {
    "self" : {
      "href" : "http://localhost:8080/test{?page,size,sort}",
      "templated" : true
    }
  },
  "_embedded" : {
    "testEntities" : [ {
      "createdBy" : {
        "username" : "xxx.admin"
      },
      "createdDate" : {
        "year" : 2014,
        "era" : 1,
        "dayOfYear" : 282,
        "dayOfWeek" : 4,
        "dayOfMonth" : 9,
        "weekOfWeekyear" : 41,
        "monthOfYear" : 10,
        "yearOfEra" : 2014,
        "yearOfCentury" : 14,
        "centuryOfEra" : 20,
        "weekyear" : 2014,
        "millisOfSecond" : 0,
        "millisOfDay" : 65724000,
        "secondOfMinute" : 24,
        "secondOfDay" : 65724,
        "minuteOfHour" : 15,
        "minuteOfDay" : 1095,
        "hourOfDay" : 18,
        "chronology" : {
          "zone" : {
            "fixed" : false,
            "uncachedZone" : {
              "cachable" : true,
              "fixed" : false,
              "id" : "Europe/London"
            },
            "id" : "Europe/London"
          }
        },
        "zone" : {
          "fixed" : false,
          "uncachedZone" : {
            "cachable" : true,
            "fixed" : false,
            "id" : "Europe/London"
          },
          "id" : "Europe/London"
        },
        "millis" : 1412874924000,
        "afterNow" : false,
        "beforeNow" : true,
        "equalNow" : false
      },
      "lastModifiedBy" : null,
      "lastModifiedDate" : {
        "year" : 2014,
        "era" : 1,
        "dayOfYear" : 282,
        "dayOfWeek" : 4,
        "dayOfMonth" : 9,
        "weekOfWeekyear" : 41,
        "monthOfYear" : 10,
        "yearOfEra" : 2014,
        "yearOfCentury" : 14,
        "centuryOfEra" : 20,
        "weekyear" : 2014,
        "millisOfSecond" : 0,
        "millisOfDay" : 65731000,
        "secondOfMinute" : 31,
        "secondOfDay" : 65731,
        "minuteOfHour" : 15,
        "minuteOfDay" : 1095,
        "hourOfDay" : 18,
        "chronology" : {
          "zone" : {
            "fixed" : false,
            "uncachedZone" : {
              "cachable" : true,
              "fixed" : false,
              "id" : "Europe/London"
            },
            "id" : "Europe/London"
          }
        },
        "zone" : {
          "fixed" : false,
          "uncachedZone" : {
            "cachable" : true,
            "fixed" : false,
            "id" : "Europe/London"
          },
          "id" : "Europe/London"
        },
        "millis" : 1412874931000,
        "afterNow" : false,
        "beforeNow" : true,
        "equalNow" : false
      },
      "title" : "Test",
      "description" : "TEST",
      "valueType" : "SINGLE",
      "attributeType" : "ATTRIBUTE",
      "feDisplay" : true,
      "new" : false,
      "_links" : {
        "self" : {
          "href" : "http://localhost:8080/test/1"
        },
        "dataType" : {
          "href" : "http://localhost:8080/test/1/dataType"
        }
      }
    } ]
  },
  "page" : {
    "size" : 20,
    "totalElements" : 1,
    "totalPages" : 1,
    "number" : 0
  }
}

EDIT: Solution

Add a custom RepositoryRestMvcConfiguration

@Configuration
public class MyRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {

    protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
        config.exposeIdsFor(TestEntity.class);
    }
}

Then change in your Application java config class the @import

Before:

@Configuration
@EnableTransactionManagement
@Import(RepositoryRestMvcConfiguration.class)
@EnableJpaRepositories(basePackages="uk.co.xxx.marketplace.data.repository")
@PropertySources({@PropertySource("classpath:hibernate.properties"),@PropertySource("classpath:persistence.properties")})
@ComponentScan(value = "uk.co.xxx.marketplace.data")
@EnableAutoConfiguration
public class Application {
...
}

Actual:

@Configuration
@EnableTransactionManagement
@Import(MyRepositoryRestMvcConfiguration.class)
@EnableJpaRepositories(basePackages="uk.co.xxx.marketplace.data.repository")
@PropertySources({@PropertySource("classpath:hibernate.properties"),@PropertySource("classpath:persistence.properties")})
@ComponentScan(value = "uk.co.xxx.marketplace.data")
@EnableAutoConfiguration
public class Application {
...
}

您可以将类RepositoryRestConfiguration(或RepositoryRestMVCConfiguration,如果使用Spring MVC)子类化,并使用您要公开其ID的域类调用方法excludeIdsFor()。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM