trouble with spark cassandra connector in java - java

I am trying to query cassandra from spark in java. Below is the code to fetch data but mapToRow method takes two parameter. first is class and second is ColumnMapper. How to get instance of the ColumnMapper class in java. Googling it recommends creating object of derived class JavaBeanColumnMapper but didn't find how JavaBeanColumnMapper class should be instantiated.
List<String> dates = Arrays.asList("2015-02-02","2015-02-08");
JavaRDD<DailyTaxlot> openTaxlots = CassandraJavaUtil.javaFunctions(sc).
cassandraTable("wedbush_praveen_testing", "cf_taxlots",CassandraJavaUtil.mapToRow(DailyTaxlot.class),).
where("openclosetag=?","Open").where("rundate IN",dates);
Any lead will be appreciated.

Have a look at the example from the spark-cassandra-connector here:
JavaApiDemo.java
In the example you can see how the Person bean class is defined. The API will instantiate it as needed for each row.
JavaRDD<Person> rdd = CassandraJavaUtil.javaFunctions(sc).cassandraTable("test", "people", mapRowTo(Person.class));
// Bean definition
public static class Person implements Serializable {
private Integer id;
private String name;
private Date birthDate;
public static Person newInstance(Integer id, String name, Date birthDate) {
Person person = new Person();
person.setId(id);
person.setName(name);
person.setBirthDate(birthDate);
return person;
}
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getBirthDate() {
return birthDate;
}
public void setBirthDate(Date birthDate) {
this.birthDate = birthDate;
}
}

Related

How to access the fields of an object in java?

I apologize, this question has already been answered once. However, the solution didn't help me.
I made a program working with an ArrayList containing name,ID and country. However, I cannot access the name, ID and country on their own, only their object as a whole. I tried using animal.name and I get the error name cannot be resolved or is not a field. I tried using methods like getName() to return the name of the object, but I got the error The method getName() is undefined for the type ArrayList<ANIMAL>. Would you please help me with that?
This is the class which, when called, creates a new object inside the ArrayList and fields of which I'm trying to access:
import java.io.*;
public class ANIMAL implements Serializable {
String nameA;
String IDA;
String countryA;
public ANIMAL(String name, String ID, String country){
nameA = name;
String IDA = ID;
String countryA = country;
}
public String getName(){
return nameA;
}
public String getCountry(){
return countryA;
}
public String getID(){
return IDA;
}
}
Your animal class:
public class Animal {
private String name;
private String id;
private String country;
public Animal (String name, String id, String country){
this.name = name;
this.id = id;
this.country = country;
}
public String getName(){
return name;
}
public String getCountry(){
return country;
}
public String getId(){
return id;
}
}
Pseudo application class (with main method for starting the application):
public class MyApp {
public static void main(String[] args) {
List<Animal> list = new ArrayList<>();
list.add(new Animal("British Bulldog", "12345", "UK"));
list.add(new Animal("Boston Terrier", "12346", "USA"));
list.add(new Animal("German Shepherd", "12347", "Germany"));
// this is a for-each loop but basically you just need
// to get an item from the list, list.get(i) would suffice
for (Animal a: list) {
System.out.println(a.getName());
}
}
}
Prints:
British Bulldog
Boston Terrier
German Shepherd
Also: I took the liberty of tidying up your code to match conventions, look at the differences and try to understand them.
Your constructor was flawed.
import java.io.*;
public class ANIMAL implements Serializable {
String name;
String ID;
String country;
public ANIMAL(String name, String ID, String country){
this.name = name;
this.ID = ID;
// String IDA = ID; doesn't assigns param ID to field ID of the class
this.country = country; //same
}
public String getName(){
return name;
}
public String getCountry(){
return country;
}
public String getID(){
return ID;
}
}
Hope this helps.

JPA: difference between setting #Id on fied and on getter

I use EclipseLink and I get very strange results. Please, consider the following code:
This code works:
#Entity
#Table(name = "someTable")
public class SomeClass{
#Id// PAY ATTENTION TO THIS LINE
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Column (name = "somecol")// PAY ATTENTION TO THIS LINE
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This code also works:
#Entity
#Table(name = "someTable")
public class SomeClass{
#Id// PAY ATTENTION TO THIS LINE
private String id;
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
//#Column (name = "somecol")// PAY ATTENTION TO THIS LINE
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This code also works:
#Entity
#Table(name = "someTable")
public class SomeClass{
private String id;
#Id// PAY ATTENTION TO THIS LINE
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
//#Column (name = "somecol")// PAY ATTENTION TO THIS LINE
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
This code DOESN'T work:
#Entity
#Table(name = "someTable")
public class SomeClass{
private String id;
#Id // PAY ATTENTION TO THIS LINE
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
#Column (name = "somecol")// PAY ATTENTION TO THIS LINE
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
I get the following exception:
Exception Description: Entity class [class SomeClass] has no primary key specified. It should define either an #Id, #EmbeddedId or an #IdClass. If you have defined PK using any of these annotations then make sure that you do not have mixed access-type (both fields and properties annotated) in your entity class hierarchy.
at org.eclipse.persistence.exceptions.ValidationException.noPrimaryKeyAnnotationsFound(ValidationException.java:1425)
at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.validatePrimaryKey(EntityAccessor.java:1542)
at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.processMappingAccessors(EntityAccessor.java:1249)
at org.eclipse.persistence.internal.jpa.metadata.accessors.classes.EntityAccessor.process(EntityAccessor.java:699)
at org.eclipse.persistence.internal.jpa.metadata.MetadataProject.processStage2(MetadataProject.java:1808)
at org.eclipse.persistence.internal.jpa.metadata.MetadataProcessor.processORMMetadata(MetadataProcessor.java:573)
at org.eclipse.persistence.internal.jpa.deployment.PersistenceUnitProcessor.processORMetadata(PersistenceUnitProcessor.java:607)
at org.eclipse.persistence.internal.jpa.EntityManagerSetupImpl.predeploy(EntityManagerSetupImpl.java:1948)
at org.eclipse.persistence.internal.jpa.deployment.JPAInitializer.callPredeploy(JPAInitializer.java:100)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactoryImpl(PersistenceProvider.java:104)
at org.eclipse.persistence.jpa.PersistenceProvider.createEntityManagerFactory(PersistenceProvider.java:188)
at org.eclipse.gemini.jpa.ProviderWrapper.createEntityManagerFactory(ProviderWrapper.java:128)
at org.eclipse.gemini.jpa.proxy.EMFServiceProxyHandler.createEMF(EMFServiceProxyHandler.java:151)
at org.eclipse.gemini.jpa.proxy.EMFServiceProxyHandler.syncGetEMFAndSetIfAbsent(EMFServiceProxyHandler.java:127)
at org.eclipse.gemini.jpa.proxy.EMFServiceProxyHandler.invoke(EMFServiceProxyHandler.java:73)
at com.sun.proxy.$Proxy8.createEntityManager(Unknown Source)
Why doesn't last code work? How to explain it?
That's because there is something like #Access which you must specify on a entity and field level if you would like to use the mixed mode. There are two values AccessType.PROPERTY and AccesType.FIELD.
The default access type is defined by where you put your identifier annotation (#Id). If you put it on the field - it will be AccessType.FIELD, if you put it on the getter - it will be AccessType.PROPERTY. - edited, not defined by JPA.
If you want to annotate not fields but properties (still having #Id on field) you must define a getter and annotate it as AccessType.PROPERTY. (or vice versa for #Id on getter).

How to ignored field in named query without creating specific domain model

I want to select object with specific field, but stored object in existing model.
#Entity
public class Car {
#Id
private Integer id;
private String name;
private String type;
private Integer year;
public Integer getId() {
return id;
}
public void setId(Integer id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getType() {
return type;
}
public void setType(String type) {
this.type = type;
}
public Integer getYear() {
return year;
}
public void setYear(Integer year) {
this.year = year;
}
}
My repository.
public interface CarRepository extends JpaRepository<Car, Integer>{
#Query("SELECT c.name, c.year FROM Car c WHERE c.year = :year")
List<Car> findAll(#Param("year") Integer year);
}
But this will give me error:
Failed to convert from type java.lang.Object[] to type com.sample.model.Car for value '{Chevrolet, 2009}'; nested exception is org.springframework.core.convert.ConverterNotFoundException: No converter found capable of converting from type java.lang.Integer to type com.sample.model.Car
You can use dynamic instantiation.
Something like this
select new Car(c.name, c.year) FROM Car c WHERE c.year = :year
or you can use a result transformer (without #Query).
And you can see this for some thoughts about partial objects loading.
UPDATE
And It needs to have Car(String name, Integer year) constructor in Car and default constructor too.

How to map the simplevalue type of Set collection using annotation

Could anyone please explain me how to use Simple value type of Set, by using annotation mapping without using one to many relationship. I have shown example in this below code. In this code I have person name and person petnames, here the person petname is the simple value type of the Set. I want map to the person name in the one table in the one table and petnames in the other table.
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
private Set<String> petname;
public Set<String> getPetname() {
return petname;
}
public void setPetname(Set<String> petname) {
this.petname = petname;
}
public boolean addPetNames(String a) {
return petname.add(a);
}
The JPA annotation works like this: (quite self explaining I think)
#ElementCollection
#CollectionTable(
name="PET_NAMES",
joinColumns=#JoinColumn(name="PERSON_ID")
)
#Column(name="PET_NAME")
private Set<String> petname;

Make pure immutable class

I have following classes :
Emp.java
final public class Emp {
private Integer id;
private String name;
private Department department;
public Emp(Integer id, String name, Department department) {
this.id = id;
this.name = name;
this.department = department;
}
public Department getDepartment() {
return department;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
}
Department.java
public class Department {
private Integer id;
private String name;
public Department(Integer id, String name) {
this.id = id;
this.name = name;
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
public void setId(Integer id) {
this.id = id;
}
public void setName(String name) {
this.name = name;
}
}
EmployeeTest.java
public class EmployeeTest {
public static void main(String args[]) {
Department dept1 = new Department(1, "dept1");
Emp emp = new Emp(1, "emp1", dept1);
emp.getDepartment().setName("dept2");
System.out.println("emp = "+emp);
}
}
Here Emp class is not purely an immutable class because somehow I am able to change the values of Department (as shown in the example).
What are the best possible changes which will make Emp class a pure Immutable class ?
In getters for non-primitive field, use this structure
public class Line {
private final Point start;
private final Point end;
public Line(final Point start, final Point end) {
this.start = new Point(start);
this.end = new Point(end);
}
public Point getStart() {
return new Point(start);
}
public Point getEnd() {
return new Point(end);
}
}
So, simply create new instance of department that is equals to previous
P.S. In my example you can see pure immutable class
EDIT:
Also you can add to Department class copy-contructor
public Department(final Department dep)
{ ... }
And to Employer
getDepartment()
{
return new Department(department);
}
See Efffective Java:
Item 15: Minimize mutability – 5 rules to follow.
Don’t provide any methods that modify the object’s state
Ensure that the class can’t be extended
Make all fields final
Make all fields private
Ensure exclusive acess to any mutable components
If you don't like removing setters and do initialization in a constructor, you can think about returning immutable (from the point of view of the Emp class) objects, which will web objects' copies, in getters (see https://stackoverflow.com/a/128712/1579085).
final public class Emp {
private Integer id;
private String name;
private Department department;
public Emp(Integer id, String name, Department department) {
this.id = id;
this.name = name;
this.department = (Department) department.clone();
}
public Department getDepartment() {
return (Department) department.clone();
}
public Integer getId() {
return id;
}
public String getName() {
return name;
}
}
And implement the method clone() in Department (which will implement the interface Cloneable) of course.
This approach is suitable, if you need to be able to modify Department, but the objects of the Emp class should be safe from those outer modifications.
make all attributes final, and remove all setters
Implement clone() in Department and make Emp return a clone of department in getDepartment().
If references to Department used in constructing Emp are available after construction, then Emp's constructor should clone given Department.

Categories