I have a Cassandra table trans_by_date with columns origin, tran_date (and some other columns). I try to run the below code get error:
java.util.NoSuchElementException: Columns not found in table trans.trans_by_date : TRAN_DATE. The column does exist.
Any syntax gotcha?
JavaRDD<TransByDate> transDateRDD = javaFunctions(sc)
.cassandraTable("trans", "trans_by_date", CassandraJavaUtil.mapRowTo(TransByDate.class))
.select(CassandraJavaUtil.column("origin"), CassandraJavaUtil.column("TRAN_DATE").as("transdate"));
public static class TransByDate implements Serializable {
private String origin;
private Date transdate;
public String getOrigin() { return origin; }
public void setOrigin(String id) { this.origin = id; }
public Date getTransdate() { return transdate; }
public void setTransdate(Date trans_date) { this.transdate = trans_date; }
}
Thanks
If you change CassandraJavaUtil.column("TRAN_DATE") to CassandraJavaUtil.column("tran_date"), i.e. only use lower-case column names, your code should work.
It seems that the CassandraJavaUtil puts the column name into double quotes when creating the select query.
See the following link for uppercase and lowercase handling in cassandra:
https://docs.datastax.com/en/cql/3.3/cql/cql_reference/ucase-lcase_r.html
Related
I am using serenitybdd to load the data from csv file but my code is unable to fetch the values from csv . Its showing null values for both xyz and abc when i am trying to print in #test metho i_setup_the_request_fields() below. What did i do wrong here?
Here is the code of java and csv file.
#RunWith(SerenityParameterizedRunner.class)
#UseTestDataFrom(value="template/test/data/response/test.csv")
public class TestCustomSteps {
private String abc;
private String xyz;
#Steps
RestAssuredSteps restAssuredSteps;
public void setAbc(String abc) {
this.abc = abc;
}
public void setXyz(String xyz) {
this.xyz = xyz;
}
#Qualifier
public String qualifier() {
return abc + "=>" + xyz;
}
#Test
#Given("I setup the request fields")
public void i_setup_the_request_fields() {
// Write code here that turns the phrase above into concrete actions
System.out.println(abc+"--"+xyz);
Map<String,String> mapData = new HashMap();
mapData.put("abc",abc);
mapData.put("xyz",xyz);
restAssuredSteps.setRequestFields(mapData);
}
}
and csv file
abc,xyz
6543210987654321,10000
6543210987654320,10000
A few things you can try one at a time:
You setter methods are not named the same as your private variables:
Try changing your variable names to cloakPan and memberId or change your setter methods to match your variable names.
#UseTestDataFrom(value="template/test/data/response/test.csv")
Maybe hard-code the full path to the file name (from root) just to make sure it is looking in the right place.
There is an example here, copy that to see if that works - http://thucydides.info/docs/thucydides/_data_driven_testing_using_csv_files.html
Versions: Datastax Java driver 3.1.4, Cassandra 3.10
Consider the following table:
create table object_ta
(
objid bigint,
version_date timestamp,
objecttype ascii,
primary key (objid, version_date)
);
And a mapped class:
#Table(name = "object_ta")
public class ObjectTa
{
#Column(name = "objid")
private long objid;
#Column(name = "version_date")
private Instant versionDate;
#Column(name = "objecttype")
private String objectType;
public ObjectTa()
{
}
public ObjectTa(long objid)
{
this.objid = objid;
this.versionDate = Instant.now();
}
public long getObjId()
{
return objid;
}
public void setObjId(long objid)
{
this.objid = objid;
}
public Instant getVersionDate()
{
return versionDate;
}
public void setVersionDate(Instant versionDate)
{
this.versionDate = versionDate;
}
public String getObjectType()
{
return objectType;
}
public void setObjectType(String objectType)
{
this.objectType = objectType;
}
}
After creating a mapper for this class (mm is a MappingManager for the session on mykeyspace)
final Mapper<ObjectTa> mapper = mm.mapper(ObjectTa.class);
On calling
mapper.save(new ObjectTa(1));
I get
Query preparation failed: INSERT INTO mykeyspace.object_ta
(objid,objid,version_date,objecttype) VALUES (?,?,?,?);:
com.datastax.driver.core.exceptions.InvalidQueryException: The column
names contains duplicates at
com.datastax.driver.core.Responses$Error.asException(Responses.java:136)
at
com.datastax.driver.core.SessionManager$4.apply(SessionManager.java:220)
at
com.datastax.driver.core.SessionManager$4.apply(SessionManager.java:196)
at
com.google.common.util.concurrent.Futures$ChainingListenableFuture.run(Futures.java:906)
at
com.google.common.util.concurrent.Futures$1$1.run(Futures.java:635)
at
java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
at
java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
at
io.netty.util.concurrent.DefaultThreadFactory$DefaultRunnableDecorator.run(DefaultThreadFactory.java:137)
at java.lang.Thread.run(Thread.java:745)
I am at a loss to understand, why the duplicate objid is generated in the query.
Thank you in advance for pointers to the problem.
Clemens
I think it is because the inconsistent use of case on the field name (objid) vs the setter/getters (getObjId). If you rename getObjId and setObjId to getObjid and setObjid respectively, I believe it might work.
In a future release, the driver mapper will allow the user to be more explicit about whether setters/getters are used (JAVA-1310) and what the naming conventions are (JAVA-1316).
I have this cassandra trigger
public class AuditTrigger implements ITrigger
{
private Properties properties = loadProperties();
public Collection<Mutation> augment(Partition update)
{
String auditKeyspace = properties.getProperty("keyspace");
String auditTable = properties.getProperty("table");
RowUpdateBuilder audit = new RowUpdateBuilder(Schema.instance.getCFMetaData(auditKeyspace, auditTable),
FBUtilities.timestampMicros(),
UUIDGen.getTimeUUID());
audit.add("keyspace_name", update.metadata().ksName);
audit.add("table_name", update.metadata().cfName);
audit.add("primary_key", update.metadata().getKeyValidator().getString(update.partitionKey().getKey()));
return Collections.singletonList(audit.build());
}
}
ho can I get the inserted value and their column name ?
Is there a way to create and use following column family with Astyanax:
CREATE TABLE mytest ( id text, subid text, clustering text, static_value text static, value text, PRIMARY KEY((id, subid), clustering));
If not, what are the best options for static columns?
The Astyanax Getting Started section contains a section on how to ensure proper serialization by annotating key fields with the "ordinal" keyword:
// Annotated composite class
Class SessionEvent{
private #Component(ordinal=0) String sessiondId;
private #Component(ordinal=1) UUID timestamp;
public SessionEvent() {
}
public int hashCode() { ... }
public boolean equals(Object o) { ... }
public int compareTo(Object o) { ... }
}
Otherwise, the Astyanax repo also has an example showing how to work directly with CQL3. To create your CF:
String CREATE_STATEMENT = "CREATE TABLE mytest ( id text, subid text, clustering text, static_value text static, value text, PRIMARY KEY((id, subid), clustering))";
try {
#SuppressWarnings("unused")
OperationResult<CqlResult<Integer, String>> result = keyspace
.prepareQuery(EMP_CF)
.withCql(CREATE_STATEMENT)
.execute();
} catch (ConnectionException e) {
logger.error("failed to create CF", e);
throw new RuntimeException("failed to create CF", e);
}
The (CQL3) link above also contains example methods that demonstrate reading and inserting as well.
This has baffled me for a while now and I cannot seem to get the grasp of it. I'm using Cell Value Factory to populate a simple one column table and it does not populate in the table.
It does and I click the rows that are populated but I do not see any values in them- in this case String values. [I just edited this to make it clearer]
I have a different project under which it works under the same kind of data model. What am I doing wrong?
Here's the code. The commented code at the end seems to work though. I've checked to see if the usual mistakes- creating a new column instance or a new tableview instance, are there. Nothing. Please help!
//Simple Data Model
Stock.java
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getstockTicker() {
return stockTicker.get();
}
public void setstockTicker(String stockticker) {
stockTicker.set(stockticker);
}
}
//Controller class
MainGuiController.java
private ObservableList<Stock> data;
#FXML
private TableView<Stock> stockTableView;// = new TableView<>(data);
#FXML
private TableColumn<Stock, String> tickerCol;
private void setTickersToCol() {
try {
Statement stmt = conn.createStatement();//conn is defined and works
ResultSet rsltset = stmt.executeQuery("SELECT ticker FROM tickerlist order by ticker");
data = FXCollections.observableArrayList();
Stock stockInstance;
while (rsltset.next()) {
stockInstance = new Stock(rsltset.getString(1).toUpperCase());
data.add(stockInstance);
}
} catch (SQLException ex) {
Logger.getLogger(WriteToFile.class.getName()).log(Level.SEVERE, null, ex);
System.out.println("Connection Failed! Check output console");
}
tickerCol.setCellValueFactory(new PropertyValueFactory<Stock,String>("stockTicker"));
stockTableView.setItems(data);
}
/*THIS, ON THE OTHER HAND, WORKS*/
/*Callback<CellDataFeatures<Stock, String>, ObservableValue<String>> cellDataFeat =
new Callback<CellDataFeatures<Stock, String>, ObservableValue<String>>() {
#Override
public ObservableValue<String> call(CellDataFeatures<Stock, String> p) {
return new SimpleStringProperty(p.getValue().getstockTicker());
}
};*/
Suggested solution (use a Lambda, not a PropertyValueFactory)
Instead of:
aColumn.setCellValueFactory(new PropertyValueFactory<Appointment,LocalDate>("date"));
Write:
aColumn.setCellValueFactory(cellData -> cellData.getValue().dateProperty());
For more information, see this answer:
Java: setCellValuefactory; Lambda vs. PropertyValueFactory; advantages/disadvantages
Solution using PropertyValueFactory
The lambda solution outlined above is preferred, but if you wish to use PropertyValueFactory, this alternate solution provides information on that.
How to Fix It
The case of your getter and setter methods are wrong.
getstockTicker should be getStockTicker
setstockTicker should be setStockTicker
Some Background Information
Your PropertyValueFactory remains the same with:
new PropertyValueFactory<Stock,String>("stockTicker")
The naming convention will seem more obvious when you also add a property accessor to your Stock class:
public class Stock {
private SimpleStringProperty stockTicker;
public Stock(String stockTicker) {
this.stockTicker = new SimpleStringProperty(stockTicker);
}
public String getStockTicker() {
return stockTicker.get();
}
public void setStockTicker(String stockticker) {
stockTicker.set(stockticker);
}
public StringProperty stockTickerProperty() {
return stockTicker;
}
}
The PropertyValueFactory uses reflection to find the relevant accessors (these should be public). First, it will try to use the stockTickerProperty accessor and, if that is not present fall back to getters and setters. Providing a property accessor is recommended as then you will automatically enable your table to observe the property in the underlying model, dynamically updating its data as the underlying model changes.
put the Getter and Setter method in you data class for all the elements.