I have a spring boot application that uses spring-boot-starter-data-mongodb (2.7.7) to link with a local mongodb (v6). I have two different classes (with a LocalDateTime property) that maps two different collections; my problem is that the LocalDateTime property of the two classes are saved like they come from different timezone in the rispective mongo collection.
First class/collection
Class
#Document("CollectionOne")
public class ClassOne{
#Id
private String id;
private LocalDateTime dataChiamata;
Repo
public interface ClassOneRepo extends MongoRepository<ClassOne, String>{}
Saving
classOneRepo.save(obj1);
Obj1.dataChiamata ( from debugger )
MongoDb CollectionOne: exact same date of java
Second class/collection
Class
#Document("CollectionTwo")
public class ClassTwo{
#Id
private String id;
private List<LocalDateTime> giorniLetti;
Repo
public interface ClassTwoRepo extends MongoRepository<ClassTwo, String> {}
Saving
classTwoRepo .save(obj2);
Obj2.giorniLetti.get(0) (from debugger)
MondoDB CollectionTwo: one hour previous respect the java
I don't understand why the two dates are saved in a different way on the db although they are exactly the same java object; any suggestion?
Related
I am trying to stream in an entire database (about 22,000 records) via Spring JPA. Using the FindAll() method I can get them in, but they are all brought into memory at once. I want to stream them.
I have tried streamAll():
#Repository
public interface GroupJsonRepository extends CrudRepository<GroupJson, String> {
Stream<GroupJson> streamAll();
}
but I get a bizarre error:
No property streamAll found for type GroupJson!
My object is:
#Entity
#Table(name = "GroupJson")
public class GroupJson {
#Id
private String id;
private String hash;
private String jsonData;
private ZonedDateTime lastUpdatedTimeStamp;
...
Is there another repository I can use that does this? I can only find CrudRepository. OR, is there some other magic JPA key words that work? I am using Spring boot 1.5.9 and I am streaming data elsewhere, but I am using a custom call:
Stream<Authority> findByPartitionKey(Long partitionKey);
You can use query if too,
#Query("select gj from Customer gj")
Stream<GroupJson> streamAll();
You have to include the "By" part in the method declaration to enable Spring Data to parse your method name. Thats the reason why you get your strange error. Spring Data interprets streamAll as a property in your entity.
#Repository
public interface GroupJsonRepository extends CrudRepository<GroupJson, String> {
Stream<GroupJson> streamAllBy();
}
I have an entity that has a filed of type java.util.Date (or Timestamp, doesn't matter for the case).
public class StatusReason {
#Column("SRN_ID")
private Long id;
#Column("SRN_CREATOR")
private String creator;
#Column("SRN_REASON")
private String reason;
#Column("SRN_STATUS")
private String status;
#Column("SRN_TIMESTAMP")
private Date timestamp;
//getters, setters, etc...
}
The database is Oracle and the corresponding column is of type TIMESTAMP(6) WITH TIME ZONE
When I call any of the default findById or findAll methods of the repository I get:
ConverterNotFoundException: No converter found capable of converting from type [oracle.sql.TIMESTAMPTZ] to type [java.util.Date].
I can create a custom RowMapper for the type and it will work fine.
I was just wondering if it's possible to register a custom converter (in my case from oracle.sql.TIMESTAMPTZ to java.util.Date) so can still benefit from the default mapping and use the converter through the whole app.
You can register custom conversions by inheriting your configuration from JdbcConfiguration (Spring Data JDBC v1.x) or AbstractJdbcConfiguration (v2.x). Then overwrite the method jdbcCustomConversions().
JdbcCustomConversions takes a list of Converter as an argument.
Can anyone exmplain the difference betwen #GraphId and #Index annotation from org.neo4j.ogm.annotation ?
For now, after reading the docs it seems that #GraphId is used to create identifier for Neo4j internal logic and users should not rely on that, because it can be reused over time. But what about #Index?
As I understand, the main advantage of graph based databases is that once we know the node/relation from which to start things become easy, since all we need to do is just traverse the graph from that starting node. And indexing helps to do so, right? So, we can write something like START n = node:index_name(property_name = value) and immitiately start exloring the graph from the indexed node by 'property_name' property, right?
So, consider this entity :
#ToString
#NodeEntity(label = "Event")
#NoArgsConstructor
public class Event{
public Event(String eventName, LocalDate dateTime){
this.name = eventName;
this.date = dateTime;
}
public Event(Long id, String eventName, LocalDate dateTime){
this(eventName, dateTime);
this.id = id;
}
#Getter
#GraphId
private Long id;
#Getter
#Index(unique = true, primary = true)
#Property(name = "name")
private String name;
#Getter
#Property(name = "date")
#Convert(DateConverter.class)
private LocalDate date;
}
As you can see the String name property is annotated with #Index. How can I write Cypher query to actually start from the node with name = 'something'? What is the index name? Or does Spring Data Neo4j 4.2.0.RELEASE figure it itself when write just MATCH (event:Event {name = 'somehting'} ... ?
#Repository
public interface EventRepository extends Neo4jRepository<Event, String>{
Event findOne(String eventName);
}
Here the repositry class and as you might see I am using String as the type of the id of the entity the repository manages, so I assume Spring uses name property of Event class to generate a query for Event findOne(String eventName);
#Index is similar to #Indexed if your are familiar with spring-data-mongodb or #Index in spring-data-jpa. Basically it indexes the field(among other things) which makes it searching for this field quite fast.
Regarding your repository method, it should be named like this
Event findByName(String eventName);
Can anyone exmplain the difference betwen #GraphId and #Index annotation from org.neo4j.ogm.annotation ?
I assume that you've checked the doc of Spring Data Neo4j. But one thing I want to add about #GraphId and #Index is that #GraphId is unique among the whole db while #Index can be the same or unique, depending on your decision.
How can I write Cypher query to actually start from the node with name = 'something'? What is the index name? Or does Spring Data Neo4j 4.2.0.RELEASE figure it itself when write just MATCH (event:Event {name = 'somehting'} ... ?
I believe you write the Cypher query in a correct way. Indices (including graph id) are maintained by the database and kept up-to-date. They are stored in a form of certain data structure. For example, B-Tree or Map, which can reduce the time of searching. You can check out your neo4j db for the indices. They are either stored in files maintained by the db (Where does Neo4j store the data?).
As for how Cypher knows the name of an index, since indices are maintained by the db and Cypher queries are also decoded by the db, it would make sense that the db can access to the index according to the Cypher query. This is just my guessing based on my understanding of DB system.
I have been looking over to many ORM's in android, by far what i have used and would fit to my app so far are ActiveAndroid and SugarOrm, but what i need is not currently supported(not supported but can be fix by creating sql scripts) as of now (one-to-many relationship). Im looking at Realm ORM for android a very promising one.
Is this possible with Realm?
// this is just a sample of what i need to do.,
// parent
class Message{
long id;
List<Meta> messages;
}
// child
class Meta{
long senderId;
String message;
Date date;
int status;
}
// I have already know how to do this on ActiveAndroid but seems a bit hard
// to update records or fetch single data.
Note: I have been having problems lately when manually creating my SQL scripts, and its very time consuming coding all of those when ORM's are there, And its very annoying when something needs to change I have to restructure most of the affected columns and etc.
I hope I had asked my question clearly and I hope there is a better way for this.
Thanks
Yes, that is very much possible with Realm. Realm is an object store, so it stores your objects as they are. In a normal object model one-to-many relationships are defined using lists, the same with Realm which has a special list called RealmList you can use.
In Realm the model you have should be defined as follow:
class Message extends RealmObject {
private long id;
private RealmList<Meta> messages;
// Getters and setters
}
class Meta extends RealmObject {
private long senderId;
private String message;
private Date date;
private int status;
// Getters and setters
}
I have two model classes:
public class AlertMatchesDTO implements Serializable
{
private static final long serialVersionUID = -3704734448105124277L;
#PrimaryKey
private String alertOid;
#Column("matches")
private List<HotelPriceDTO> matches;
...
}
public class HotelPriceDTO implements Serializable
{
private static final long serialVersionUID = -8751629882750913707L;
private Long hotelOid;
private double priceByNight;
private Date checkIn;
private Date checkOut;
...
}
and I want to persist instances of the first class in a Cassandra column family using Spring Data. In particular using Cassandra template like this:
...
cassandraTemplate.insert(dto, writeOptions);
...
and Spring Data have problems serializing List<HotelPriceDTO>. What I think I need is a way to tell cassandraTemplate how to convert the type. In the official documentation, there is a chapter telling that I have to use CassandraMappingConverter and MappingCassandraConverter, but they do not provide an example yet.
My question is: is there an example of how to register a converter like this (in the test code of the project, may be?) or any other example I can use while the official documentation is completed? Thanks in advance.
Hate to say this, but you should RTFM at http://docs.spring.io/spring-data/cassandra/docs/1.1.0.RELEASE/reference/html/.
Having said that, I noticed the DTO suffixes on your class names, which implies to me that you may not have a domain model, only a service layer with DTOs. If that's the case, you might consider defining the mappings yourself as RowMapper implementations and simply use CqlTemplate without the bells & whistles of Spring Data Cassandra. If you choose to fuse the architectural concepts of DTO and entity (entity being a persistent domain object), you're free to use Spring Data Cassandra along with the mapping metadata required (#Table, #PrimaryKeyColumn, etc). Your choice.
See http://goo.gl/gPBFpu for more reading on the subject of entities v. DTOs.