I have an Entity Person :
#Entity
public class Person implements Serializable {
#Id
#GeneratedValue(strategy = AUTO, generator = "PERSON_SEQ")
private Integer idPerson;
private String lastName;
private String firstName;
#Lob
private byte[] picture;
A repository
public interface PersonRepository extends PagingAndSortingRepository<Person, Integer> {}
A projection
#Projection(name = "picture", types = { Person.class })
public interface ProjectionPicturePerson {
byte[] getPicture();
}
When i used the projection : ..../persons/1?projection=picture
i have this error
There was an unexpected error (type=Internal Server Error, status=500).
Could not write content: [B cannot be cast to [Ljava.lang.Object; (through reference chain: org.springframework.data.rest.webmvc.json.["content"]->$Proxy109["picture"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: [B cannot be cast to [Ljava.lang.Object; (through reference chain: org.springframework.data.rest.webmvc.json.["content"]->$Proxy109["picture"])
When i use a projection on a String, exemple lastName it works
#Projection(name = "lastName", types = { Person.class })
public interface ProjectionLastName {
String getLastName();
}
When i don't use projection it works too
jackson serialize the image attribute
Is there a restriction on Blob ?
That's a bug in ProxyProjectionFactory. I've filed and fixed DATACMNS-722 for you scheduled to be in the upcoming services releases (mid next week).
Related
I have the following entity:
#Entity
public class SystemLogEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long id;
private long creationTime;
private String thread;
private int severity;
#Lob
private String message;
#ElementCollection(fetch = FetchType.EAGER)
#Lob
private List<String> stacktrace;
...
}
My Respository implements JpaSpecificationExecutor, which allows me to use Specifications to filter my db requests:
#Repository
public interface SystemLogRepository extends JpaRepository<SystemLogEntity, Long>, JpaSpecificationExecutor<SystemLogEntity> {
public List<SystemLogEntity> findAll(Specification spec);
}
For the simple field of the SystemLogEntity this works fine, the Predicate are straight forward.
Also if I filter for an exact item in a collection, the Predicate are still straight forward (in).
But how can I filter my SystemLogEntity after a stack trace collection item which is LIKE a given value?
In other words, I would e.g. like to filter SystemLogEntity after the term NullpointerException. Is this even possible with Predicate?
I hope this will work:
Specification<SystemLogEntity> stacktraceLike(String stacktrace) {
return (root, query, cb) -> cb.like(root.join("stacktrace"), "%" + stacktrace + "%");
}
More examples...
I have a existing Model and want to use it with Picketlink. But I am using Long as #Id field. But Picketlink expect this to be a String field. I have found some hints to use another entity which maps to the corresponding entity of my model. But actually I don't now how to do it.
I have a base class, which all entities derive from:
#MappedSuperclass
public abstract class AbstractEntity implements Serializable, Cloneable {
#Id
#Identifier
#Column(name = "SID")
private Long sid;
#Column(name = "INSERT_TIME")
private Date insertTime;
#Column(name = "UPDATE_TIME")
private Date updateTime;
// getters and setters
}
And a derived realm entity:
#Entity
#IdentityManaged(Realm.class)
public class RealmEntity extends AbstractEntity {
#AttributeValue
private String name;
#PartitionClass
private String typeName;
#ConfigurationName
private String configurationName;
#AttributeValue
private boolean enforceSSL;
#AttributeValue
private int numberFailedLoginAttempts;
// getters and setters
}
And the mapping class for Picketlink looks as follows:
#IdentityPartition(supportedTypes = {
Application.class,
User.class,
Role.class
})
public class Realm extends AbstractPartition {
#AttributeProperty
private boolean enforceSSL;
#AttributeProperty
private int numberFailedLoginAttempts;
private Realm() {
this(null);
}
public Realm(String name) {
super(name);
}
}
The PartitionManager is defined as follows:
builder
.named("default.config")
.stores()
.jpa()
.supportType(User.class, Role.class, Application.class, Realm.class)
.supportGlobalRelationship(Grant.class, ApplicationAccess.class)
.mappedEntity(App.class, AppUserRole.class, AppRole.class, AppUser.class, UserEntity.class, RelationshipIdentityTypeEntity.class, RealmEntity.class)
.addContextInitializer((context, store) -> {
if (store instanceof JPAIdentityStore) {
if (!context.isParameterSet(JPAIdentityStore.INVOCATION_CTX_ENTITY_MANAGER)) {
context.setParameter(JPAIdentityStore.INVOCATION_CTX_ENTITY_MANAGER, entityManager);
}
}
});
When I try to create a new Realm Hibernate throws an error while trying to load the Realm because the #Id is defined as Long but the #Identifier of the Picketlink model is a String.
this.shsRealm = new Realm(REALM_SHS_NAME);
this.shsRealm.setEnforceSSL(true);
this.shsRealm.setNumberFailedLoginAttempts(3);
this.partitionManager.add(this.shsRealm);
java.lang.IllegalArgumentException: Provided id of the wrong type for class de.logsolut.common.picketlink.model.RealmEntity. Expected: class java.lang.Long, got class java.lang.String
How can I map the JPA model correctly to Picketlink?
I tried hard to build an example to save my enity like below:
Resource class has ResourceDetail in which I defined GeoJsonPoint.
#Document(collection = "Resource")
public class Resource implements Serializable {
/**
*
*/
private static final Long serialVersionUID = 1L;
#Id
private Long id;
private String name;
private Integer age;
private String orgName;
private String resourceType;
private String department;
private boolean showPrice;
private Integer price;
private ResourceDetail resourceDetail;
}
#Document(collection = "ResourceDetail")
public class ResourceDetail implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private String identityNumber;
#DateTimeFormat(iso = ISO.DATE)
private Date birthDate;
private String addressLine1;
private String addressLine2;
private String specialization;
private GeoJsonPoint location;
}
I have added following mapper also in Appconfig:
#Configuration
#ComponentScan(basePackages = "com.test")
#EnableWebMvc
public class AppConfig extends WebMvcConfigurerAdapter {
#Bean
public MongoDbFactory mongoDbFactory() throws Exception {
return new SimpleMongoDbFactory(new MongoClient(), "test");
}
#Bean
public MongoTemplate mongoTemplate() throws Exception {
MongoTemplate mongoTemplate = new MongoTemplate(mongoDbFactory());
return mongoTemplate;
}
/**
* Read JSON data from disk and insert those stores.
*
* #return
*/
public #Bean ObjectMapper repositoryPopulator() {
ObjectMapper mapper = new ObjectMapper();
mapper.addMixIn(GeoJsonPoint.class, GeoJsonPointMixin.class);
mapper.configure(DeserializationFeature.FAIL_ON_UNKNOWN_PROPERTIES, false);
return mapper;
}
static abstract class GeoJsonPointMixin {
GeoJsonPointMixin(#JsonProperty("longitude") double x, #JsonProperty("latitude") double y) {
}
}
}
I am getting this error:
{
"timestamp": 1445857673601,
"status": 400,
"error": "Bad Request",
"exception": "org.springframework.http.converter.HttpMessageNotReadableException",
"message": "Could not read JSON: No suitable constructor found for type [simple type, class org.springframework.data.mongodb.core.geo.GeoJsonPoint]: can not instantiate from JSON object (need to add/enable type information?)\n at [Source: java.io.PushbackInputStream#d7eff8; line: 13, column: 25] (through reference chain: com.appointment.domain.Resource[\"resourceDetail\"]->com.appointment.domain.ResourceDetail[\"location\"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: No suitable constructor found for type [simple type, class org.springframework.data.mongodb.core.geo.GeoJsonPoint]: can not instantiate from JSON object (need to add/enable type information?)\n at [Source: java.io.PushbackInputStream#d7eff8; line: 13, column: 25] (through reference chain: com.appointment.domain.Resource[\"resourceDetail\"]->com.appointment.domain.ResourceDetail[\"location\"])",
"path": "/rest/resource/add"
}
I used this format to save my enity with GeoJsonPoint:
{
"name":"Test",
"age": 32,
"orgName":"testOrg",
"resourceType":"testresourcType",
"price":1200,
"department":"testDepartment",
"resourceDetail": {
"identityNumber": "3",
"birthDate": "2000-10-10",
"location" : { "latitude":40.743827, "longitude":-73.989015 }
}
Please help me to solve this. Thanks
Probably late, but you need to use GeoJSON format in your mongo.
"location" : {
"type" : "Point",
"coordinates" : [
-2.6637,
54.6944
]
}
be aware that coordinates are in this order : longitude, latitude
See more :
http://geojson.org/
http://docs.spring.io/spring-data/mongodb/docs/current/api/org/springframework/data/mongodb/core/geo/GeoJson.html
Tested your Mixin code an it worked. Although, I would suggest you to make sure you are sending application/json as content type and the json structure is correct (In your example there is a missing }).
There is a similar question like yours and this issue can be solved by registering a GeoJsonModule as well: https://stackoverflow.com/a/37340077/3697851
I'm using Spring JPA 1.7 and QueryDSL 3.5.1. I am getting 'No property find found' error.
Here are my classes.
#Entity
#Table(name="Device")
public class Device implements Serializable {
private static final long serialVersionUID = 1L;
#NotEmpty
#Id
#Column(name="deviceId")
private String deviceId="";
#Column(name="accountId")
private String accountId="";
#Column(name="groupId")
private String groupId="";
#Column(name="equipmentType")
private String equipmentType="";
#Column(name="deviceCode")
private String deviceCode="";
#Column(name="deviceType")
private String deviceType="";
#NotEmpty
#Column(name="simId")
private String simId="";
#NotEmpty
#Column(name="imeiNumber")
private String imeiNumber="";
#Column(name="simPhoneNumber")
private String simPhoneNumber="";
#Column(name="driverId")
private String driverId="";
#Column(name="pushpinId")
private String pushpinId=""; //who registered device? JMA/MDM/JAMS
#Column(name="isActive", columnDefinition="INT(1)")
private boolean isActive = false;
#Column(name="displayName")
private String displayName="";
#Column(name="description")
private String description="";
#Column(name="notes")
private String notes="";
#Column
#JsonSerialize(using=DateSerializer.class)
private long creationTime;
#Column
#JsonSerialize(using=DateSerializer.class)
private long lastUpdateTime;
//Getters and setters
}
public interface DeviceRepository extends PagingAndSortingRepository<Device, String>, DeviceRepositoryCustom {
public Page<Device> findAll(com.mysema.query.types.Predicate predicate, Pageable pageable);
}
public interface DeviceRepositoryCustom {
public List<Device> selectByEquipmentTypeAndAnyColumnLike(String equipmentType, String creationTime, String searchField, String searchText, boolean hasPushId);
}
public class MdmPredicates {
public static com.mysema.query.types.Predicate anyFieldLike(String field, String text) {
QDevice device = QDevice.device;
//Do something later
return device.deviceId.contains(text);
}
}
Here is the error log:
aused by: org.springframework.data.mapping.PropertyReferenceException: No property find found for type entities.Device
at org.springframework.data.mapping.PropertyPath.<init>(PropertyPath.java:75)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:327)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:353)
at org.springframework.data.mapping.PropertyPath.create(PropertyPath.java:307)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:271)
at org.springframework.data.mapping.PropertyPath.from(PropertyPath.java:245)
at org.springframework.data.repository.query.parser.Part.<init>(Part.java:72)
at org.springframework.data.repository.query.parser.PartTree$OrPart.<init>(PartTree.java:188)
at org.springframework.data.repository.query.parser.PartTree$Predicate.buildTree(PartTree.java:277)
at org.springframework.data.repository.query.parser.PartTree$Predicate.<init>(PartTree.java:257)
at org.springframework.data.repository.query.parser.PartTree.<init>(PartTree.java:68)
at org.springframework.data.jpa.repository.query.PartTreeJpaQuery.<init>(PartTreeJpaQuery.java:57)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:90)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$CreateIfNotFoundQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:162)
at org.springframework.data.jpa.repository.query.JpaQueryLookupStrategy$AbstractQueryLookupStrategy.resolveQuery(JpaQueryLookupStrategy.java:68)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.<init>(RepositoryFactorySupport.java:290)
at org.springframework.data.repository.core.support.RepositoryFactorySupport.getRepository(RepositoryFactorySupport.java:158)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:162)
at org.springframework.data.repository.core.support.RepositoryFactoryBeanSupport.getObject(RepositoryFactoryBeanSupport.java:44)
at org.springframework.beans.factory.support.FactoryBeanRegistrySupport.doGetObjectFromFactoryBean(FactoryBeanRegistrySupport.java:168)
I know that the error happens when I don't use real column name instead of property name. But the property names in the class are all same with column names.
Would you please tell me what I am I missing?
Your help would be appreciated.
I have a Gfh_i18n entity, with a composite key (#IdClass):
#Entity #IdClass(es.caib.gesma.petcom.data.entity.id.Gfh_i18n_id.class)
public class Gfh_i18n implements Serializable {
#Id #Column(length=10, nullable = false)
private String localeId = null;
#Id <-- This is the attribute causing issues
private Gfh gfh = null;
....
}
And the id class
public class Gfh_i18n_id implements Serializable {
private String localeId = null;
private Gfh gfh = null;
...
}
As this is written, this works. The issue is that I also have a Gfh class which will have a #OneToMany relationship to Gfh_i18n:
#OneToMany(mappedBy="gfh")
#MapKey(name="localeId")
private Map<String, Gfh_i18n> descriptions = null;
Using Eclipse Dali, this gives me the following error:
In attribute 'descriptions', the "mapped by" attribute 'gfh' has an invalid mapping type for this relationship.
If I just try to do, in Gfh_1i8n
#Id #ManyToOne
private Gfh gfh = null;
it solves the previous error but gives one in Gfh_i18n, stating that
The attribute matching the ID class attribute gfh does not have the correct type es.caib.gesma.petcom.data.entity.Gfh
This question is similar to mine, but I do not fully understand why I should be using #EmbeddedId (or if there is some way to use #IdClass with #ManyToOne).
I am using JPA 2.0 over Hibernate (JBoss 6.1)
Any ideas? Thanks in advance.
You are dealing with a "derived identity" (described in the JPA 2.0 spec, section 2.4.1).
You need to change your ID class so the field corresponding to the "parent" entity field in the "child" entity (in your case gfh) has a type that corresponds to either the "parent" entity's single #Id field (e.g. String) or, if the "parent" entity uses an IdClass, the IdClass (e.g. Gfh_id).
In Gfh_1i8n, you should declare gfh like this:
#Id #ManyToOne
private Gfh gfh = null;
Assuming GFH has a single #Id field of type String, your ID class should look like this:
public class Gfh_i18n_id implements Serializable {
private String localeId = null;
private String gfh = null;
...
}