Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Date saved but retrieved null in ElementCollection (or Embedded) property #1000

Closed
mj3c opened this issue Apr 11, 2018 · 5 comments
Closed
Labels
Milestone

Comments

@mj3c
Copy link

mj3c commented Apr 11, 2018

I have an object of type Instance which contains an @ElementCollection of type Datapoint. Each datapoint has a timestamp and a value. In a test, I create some instances with their datapoints and save them, however, when I read any of those instances back from the database, the value for datapoints is set but the timestamp is null.

I am using:
Cassandra 3.11.2
Kundera 3.12

persistence.xml

    <persistence-unit name="cassandra_pu">
        <provider>com.impetus.kundera.KunderaPersistence</provider>
        <properties>
            <property name="kundera.nodes" value="localhost"/>
            <property name="kundera.port" value="9042"/>
            <property name="kundera.keyspace" value="d2lablite"/>
            <property name="kundera.dialect" value="cassandra"/>
            <property name="kundera.ddl.auto.prepare" value="create" />
            <property name="kundera.client.lookup.class" value="com.impetus.kundera.client.cassandra.dsdriver.DSClientFactory" />
        </properties>
    </persistence-unit>

Datapoint.java

@Embeddable
public class Datapoint {
    @Column(name="timestamp")
    @Temporal(TemporalType.TIMESTAMP)
    private java.util.Date timestamp;

    @Column(name="value")
    private double value;

    public Datapoint() { }

    // Getters, setters
}

Instance.java

@Entity
@Table(name="instances")
public class Instance {
    @Id
    @Column(name="uuid")
    private String uuid;

    @Column(name="param")
    private String param;

    @ElementCollection
    @Column(name="datapoints")
    private List<Datapoint> datapoints;

    @ElementCollection
    @Column(name="metadata")
    private Map<String, String> metadata;

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

    public Instance() { }
}

So what I do is:

  • Create an Instance, create a List<Datapoint>, set it to instance and persist the instance
  • Check via cqlsh that the instance is saved and all datapoints have the timestamp saved as well
  • Use the EntityManager's find method to fetch an instance by its uuid, and it contains all values, including the date column, and its datapoints contain their values but the timestamp field in every datapoint is null.

I have also tried to use @Embedded and only 1 Datapoint instead of a list and the result is the same, timestamp is null.

What did I miss?

@devender-yadav
Copy link
Contributor

Hi @milosjajac,

I will try to replicate this on Monday.

-Dev

@devender-yadav
Copy link
Contributor

devender-yadav commented Apr 16, 2018

Hi @milosjajac, working fine for me.

public static void main(String[] args)
{

    Map<String, String> props = new HashMap<String, String>();
    props.put(CassandraConstants.CQL_VERSION, CassandraConstants.CQL_VERSION_3_0);
    EntityManagerFactory emf = Persistence.createEntityManagerFactory("issue_pu", props);

    EntityManager em = emf.createEntityManager();

    Datapoint dp1 = new Datapoint();
    dp1.setValue(10.01);
    dp1.setTimestamp(new Date());

    Datapoint dp2 = new Datapoint();
    dp2.setValue(11.01);
    dp2.setTimestamp(new Date());

    List<Datapoint> list = new ArrayList<>();
    list.add(dp1);
    list.add(dp2);

    Instance instance = new Instance();
    instance.setDatapoints(list);
    instance.setDate(new Date());
    instance.setParam("some-param");

    String id = UUID.randomUUID().toString();

    instance.setUuid(id);

    em.persist(instance);
    Instance inst = em.find(Instance.class, id);

    List<Datapoint> dps = inst.getDatapoints();

    for (Datapoint datapoint : dps)
    {
        System.out.println(datapoint.getTimestamp());
    }

 }

@mj3c
Copy link
Author

mj3c commented Apr 17, 2018

Thank you @devender-yadav for getting back to this.

I have tried your example and it does work when I use find() to retrieve a single instance, however, how would I do this to retrieve a list of instances from Cassandra?

  • I have tried doing createNativeQuery("SELECT * FROM instances", Instance.class) but the datapoint timestamps are null (even though the instance date is loaded correctly).
  • I have also tried createQuery("SELECT i FROM Instance i", Instance.class) but this yields an exception I found in another issue here, sadly without a solution.

One more thing I have noticed aside from this is that closing the EntityManager, getting a new one from the factory and trying find() on it leads to an exception with the message "undefined column name key", leading me to believe that for some reason the second EntityManager does not know that the id column is named "uuid". Should I never close the initial EntityManager and always use it instead?

I could not find any information on these two matters when reading the docs.

@devender-yadav
Copy link
Contributor

Hi @milosjajac,

Seems like an issue from Kundera side.

@devender-yadav
Copy link
Contributor

Hi @milosjajac,

This issue is fixed and will be available in the next Kundera release.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

3 participants