我们正在尝试使用 Spring-Data-JPA 和 Spring-Data-Rest 进行 POC。 输出看起来异常,我们有实体字段的值,除了 id,id 字段设置在抽象类中。
我们正在使用一个简单的实体女巫扩展 AbstractPersistable(它是一个 spring-data-jpa 类 http://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/domain/AbstractPersistable.html)。
这里是这个的源代码:
@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;
}
}
和我们的实体:
@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 ...}
}
然后是服务(使用 spring-data-rest):
@RepositoryRestResource(path = "test")
public interface TestEntityRepository extends JpaRepository<TestEntity, Long> {
}
我们使用 Spring boot 运行应用程序,Chrome 上的输出(URL 是 http://localhost:8080/test)是一个 JSON + HAL 数据(没有显示 id !!! ):
{
"_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
}
}
另一件事是,当我们在 TestEntity ( http://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/domain/AbstractAuditable.html ) 上使用 AbstractAuditable 时,它起作用了,我们从 AbstractAuditable 获得了字段值,但我们仍然没有获得 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();
}
}
和JSON+HAL结果:
{
"_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
}
}
编辑:解决方案
添加自定义 RepositoryRestMvcConfiguration
@Configuration
public class MyRepositoryRestMvcConfiguration extends RepositoryRestMvcConfiguration {
protected void configureRepositoryRestConfiguration(RepositoryRestConfiguration config) {
config.exposeIdsFor(TestEntity.class);
}
}
然后在您的应用程序 java 配置类中更改 @import
之前:
@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 {
...
}
实际:
@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 的域类调用方法 exposeIdsFor()。
关于java - 无法在 JSON 输出中获取 JPA 实体 ID,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26296252/
我在从html页面生成PDF时遇到问题。我正在使用PDFkit。在安装它的过程中,我注意到我需要wkhtmltopdf。所以我也安装了它。我做了PDFkit的文档所说的一切......现在我在尝试加载PDF时遇到了这个错误。这里是错误:commandfailed:"/usr/local/bin/wkhtmltopdf""--margin-right""0.75in""--page-size""Letter""--margin-top""0.75in""--margin-bottom""0.75in""--encoding""UTF-8""--margin-left""0.75in""-
为了将Cucumber用于命令行脚本,我按照提供的说明安装了arubagem。它在我的Gemfile中,我可以验证是否安装了正确的版本并且我已经包含了require'aruba/cucumber'在'features/env.rb'中为了确保它能正常工作,我写了以下场景:@announceScenario:Testingcucumber/arubaGivenablankslateThentheoutputfrom"ls-la"shouldcontain"drw"假设事情应该失败。它确实失败了,但失败的原因是错误的:@announceScenario:Testingcucumber/ar
我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在
我尝试运行2.x应用程序。我使用rvm并为此应用程序设置其他版本的ruby:$rvmuseree-1.8.7-head我尝试运行服务器,然后出现很多错误:$script/serverNOTE:Gem.source_indexisdeprecated,useSpecification.Itwillberemovedonorafter2011-11-01.Gem.source_indexcalledfrom/Users/serg/rails_projects_terminal/work_proj/spohelp/config/../vendor/rails/railties/lib/r
我正在使用puppet为ruby程序提供一组常量。我需要提供一组主机名,我的程序将对其进行迭代。在我之前使用的bash脚本中,我只是将它作为一个puppet变量hosts=>"host1,host2"我将其提供给bash脚本作为HOSTS=显然这对ruby不太适用——我需要它的格式hosts=["host1","host2"]自从phosts和putsmy_array.inspect提供输出["host1","host2"]我希望使用其中之一。不幸的是,我终其一生都无法弄清楚如何让它发挥作用。我尝试了以下各项:我发现某处他们指出我需要在函数调用前放置“function_”……这
我正在尝试在我的centos服务器上安装therubyracer,但遇到了麻烦。$geminstalltherubyracerBuildingnativeextensions.Thiscouldtakeawhile...ERROR:Errorinstallingtherubyracer:ERROR:Failedtobuildgemnativeextension./usr/local/rvm/rubies/ruby-1.9.3-p125/bin/rubyextconf.rbcheckingformain()in-lpthread...yescheckingforv8.h...no***e
我花了三天的时间用头撞墙,试图弄清楚为什么简单的“rake”不能通过我的规范文件。如果您遇到这种情况:任何文件夹路径中都不要有空格!。严重地。事实上,从现在开始,您命名的任何内容都没有空格。这是我的控制台输出:(在/Users/*****/Desktop/LearningRuby/learn_ruby)$rake/Users/*******/Desktop/LearningRuby/learn_ruby/00_hello/hello_spec.rb:116:in`require':cannotloadsuchfile--hello(LoadError) 最佳
在我的Controller中,我通过以下方式在我的index方法中支持HTML和JSON:respond_todo|format|format.htmlformat.json{renderjson:@user}end在浏览器中拉起它时,它会自然地以HTML呈现。但是,当我对/user资源进行内容类型为application/json的curl调用时(因为它是索引方法),我仍然将HTML作为响应。如何获取JSON作为响应?我还需要说明什么? 最佳答案 您应该将.json附加到请求的url,提供的格式在routes.rb的路径中定义。这
我真的很习惯使用Ruby编写以下代码:my_hash={}my_hash['test']=1Java中对应的数据结构是什么? 最佳答案 HashMapmap=newHashMap();map.put("test",1);我假设? 关于java-等价于Java中的RubyHash,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/22737685/
这是一道面试题,我没有答对,但还是很好奇怎么解。你有N个人的大家庭,分别是1,2,3,...,N岁。你想给你的大家庭拍张照片。所有的家庭成员都排成一排。“我是家里的friend,建议家庭成员安排如下:”1岁的家庭成员坐在这一排的最左边。每两个坐在一起的家庭成员的年龄相差不得超过2岁。输入:整数N,1≤N≤55。输出:摄影师可以拍摄的照片数量。示例->输入:4,输出:4符合条件的数组:[1,2,3,4][1,2,4,3][1,3,2,4][1,3,4,2]另一个例子:输入:5输出:6符合条件的数组:[1,2,3,4,5][1,2,3,5,4][1,2,4,3,5][1,2,4,5,3][