How to update values of HashMap fields of objects cached in Coherence? - distributed-caching

There is a java bean with following Map field:
private Map<String, Long> items;
public Map<String, Long> getItems() {
return items;
}
public void setItems(Map<String, Long> items) {
this.items = items;
}
Is it any chance to get this items field updated for objects cached in a Coherence distributed cache using Coherence Query Language?
Something like:
update "order-cache" set items = new HashMap<String, Long>() {{put("001",2L);}} where key()=”1”

It could be done with Guava's ImmutableMap:
update "order-cache" set items = com.google.common.collect.ImmutableMap.of("001",2L) where key()="1"
This solution is good only for objects with up to 5 items in the HashMap field.

Related

Mock Projection Result Spring Data JPA

I am using spring data jpa in my spring boot project.
I am firing an JPQL query and using an projection to store the result of query.
My Projection :
public interface VeryBasicProjection {
String getTitle();
String getUrl();
}
My service calling this projection :
public List<VeryBasicDTO> getLatestData(int limit){
// Pageable for Limit
Pageable pageable = new PageRequest(0, limit);
// Get Data from DB
List<VeryBasicProjection> latestData = tableRepository.getLatestData("live", 2,pageable);
List<VeryBasicDTO> responseDTO = new ArrayList<>();
// Map Projection to DTO
for(VeryBasicProjection veryBasicProjection : latestData){
VeryBasicDTO veryBasicDTO = new VeryBasicDTO();
veryBasicDTO.buildDTO(veryBasicProjection);
responseDTO.add(veryBasicDTO);
}
return responseDTO;
}
Now I want to test this service using Mockito(Unit Test Case)
I am mocking the call to repository
using when and thenReturn.
My question is how do I mock the result of repository? What should be in thenReturn? I mean how do I create instance of projection and setData to it?
If you want to create an instance of your projection without creating a class implementing the interface, you can use SpelAwareProxyProjectionFactory.
import org.springframework.data.projection.ProjectionFactory;
import org.springframework.data.projection.SpelAwareProxyProjectionFactory;
// ...
ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
VeryBasicProjection projection = factory.createProjection(VeryBasicProjection.class);
projection.setTitle("theTitle");
projection.setUrl("theUrl");
You also need to add setters in your projection:
public interface VeryBasicProjection {
String getTitle();
String getUrl();
void setTitle(String title);
void setUrl(String url);
}
Source: https://github.com/spring-projects/spring-data-examples/blob/master/rest/projections/src/test/java/example/springdata/rest/projections/SimpleProjectionTests.java
This is the simplest way to mock projections in TEST
VeryBasicProjection VeryBasicProjection = new VeryBasicProjection() {
String getTitle() {
return "Title";
}
String getUrl() {
return "url";
}
};
As an addition to Nis' answer:
If the interface doesn't have setters, the projection can be initialized with a map:
ProjectionFactory factory = new SpelAwareProxyProjectionFactory();
Map<String, String> map = Map.of(
"title", "theTitle",
"url", "theUrl"
);
VeryBasicProjection projection = factory.createProjection(VeryBasicProjection.class, map);
We have implemented the same stuff in below way
First mocked the two type of objects:
#Mock
private EntityManager em;
#Mock
private DemoProjectRepo demoProjectRepo;
My demoProjectRepo.findByAll returns List<DemoProjectDevices>
DemoProjectDevices device1 = new DemoProjectDevices();
device1.setAcctNbr("2365897412236589");
device1.setdeviceSeq(new BigDecimal(1));
device1.setCrteTms("2017-07-29 01:21:44.910807");
List<DemoProjectDevices> demoProjectDevices = new ArrayList<DemoProjectDevices>();
demoProjectDevices.add(device1);
For the mock when and thenReturn:
Mockito.when(demoProjectRepo.findByAll("2365897412236589", em))
.thenReturn(demoProjectDevices);
In your projection interface you need to add setters for the values you have getters for.
So when you have a concrete class implementing the projection interface you can add the values to that class so you might have something along these lines:
public interface VeryBasicProjection {
String getTitle();
String getUrl();
void setTitle(String title);
void setUrl(String url);
}
public class VeryBasicProjectionImpl implements VeryBasicProjection{
//add implementing methods
}
////
#Mock
Repository tableRepo;
#InjectMocks
ClassUnderTest c;
#Test
public void test(){
// Pageable for Limit
Pageable pageable = new PageRequest(0, limit);
VeryBasicProjection vbp = new VeryBasicProjectionImpl();
// add data to object here using the setters
List<VeryBasicProjection> projList = new ArrayList<>()
//add objects created
when(tableRepo.getLatestData("live", 2, pageable)).thenReturn(projList));
}

NullPointerException in Custom Dstinct Mapper

i am using hazelcast 3.6.1 and implementing distinct aggregate functionality using custom mapreduce to get solr facet kind of results.
public class DistinctMapper implements Mapper<String, Employee, String, Long>{
private transient SimpleEntry<String, Employee> entry = new SimpleEntry<String, Employee>();
private static final Long ONE = Long.valueOf(1L);
private Supplier<String, Employee, String> supplier;
public DistinctMapper(Supplier<String, Employee, String> supplier) {
this.supplier = supplier;
}
#Override
public void map(String key, Employee value, Context<String, Long> context) {
System.out.println("Object "+ entry + " and key "+key);
entry.setKey(key);
entry.setValue(value);
String fieldValue = (String) supplier.apply(entry);
//getValue(value, fieldName);
if (null != fieldValue){
context.emit(fieldValue, ONE);
}
}
}
and mapper is failing with NullPointerException. and sysout statement says entry object is null.
SimpleEntry : https://github.com/hazelcast/hazelcast/blob/v3.7-EA/hazelcast/src/main/java/com/hazelcast/mapreduce/aggregation/impl/SimpleEntry.java
Can you point me the issue in the above code ? Thanks.
entry field is transient. This means that it is not serialized, so when DistinctMapperobject is deserialized on hazecalst node, it's value is null.
Removing the transient will solve the NullPointerException.
On the side note:
Why do you need this entry field? It doesn't seem to have any use.

What layer is responsible for implementing a LazyLoading strategy for children objects of an entity

Let's say you have an order as an aggregate root. An order contains one or more line items.
It is my understanding that it's the repository's responsibility to instantiate an order object when asked.
The line items can be loaded at the time of the order object's creation (eager loaded), or the line item collection can be populated when it is accessed by the client code (lazy loaded).
If we are using eager loading, it's seems that the repository code would take responsibility with hydrating the line items when the order is created.
However if we are using lazy loading, how is the repository called when the LineItems collection is accessed without creating a dependency on the repository from the order domain class?
Main problem is in Repository's ability to get only aggregate roots (presenting aggregates), thus you cannot use Repository to get line items. This can lead to aggregate encapsulation violation.
I propose something like:
//Domain level:
public interface IOrderItemList {
IEnumerable<OrderItem> GetItems();
}
public class Order {
private IOrderItemList _orderItems;
public IEnumerable<OrderItem> OrderItems
{ get { return _orderItems.GetItems() } };
public Order(IOrderItemList orderItems)
{
_orderItems = orderItems;
}
}
public class OrderItemList : IOrderItemList
{
private IList<OrderItem> _orderItems;
public IEnumerable<OrderItem> GetItems() {
return _orderItems; //or another logic
}
//other implementation details
}
//Data level
public class OrderItemListProxy : IOrderItemList
{
//link to 'real' object
private OrderItemList _orderItemList;
private int _orderId;
//alternatively:
//private OrderEntity _orderEntity;
//ORM context
private DbContext _context;
public OrderItemListProxy(int orderId, DbContext context)
{
_orderId = orderId;
_context = context;
}
public IEnumerable<OrderItem> GetItems() {
if (_orderItemList == null)
{
var orderItemEntities = DbContext.Orders
.Single(order => order.Id == _orderId).OrderItems;
var orderItems = orderItemEntites.Select(...);
//alternatively: use factory to create OrderItem from OrderItemEntity
_orderItemList = new OrderItemList(orderItems);
}
return _orderItemList.GetItems();
}
}
public class OrderRepository
{
//ORM context
private DbContext _context;
Order GetOrder(int id)
{
var orderEntity = _context.Single(order => order.Id == id);
var order = new Order(new OrderItemListProxy(id, _context))
//alternatively:
//var order = new Order(new OrderItemListProxy(orderEntity, _context))
...
//init other fields
...
}
//other methods
...
}
Most important here is that IOrderItemList corresponds to domain layer, but OrderItemListProxy corresponds to data layer.
Finally,
You may use IList<OrderItem> instead of custom IOrderItemList or another appropriate interface.
Proxy implementation may differ.
I don't provide best practicies for using db context, it may depend on technologies you use.

Javafx PropertyValueFactory not populating Tableview

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.

Sorting tree nodes in Primefaces

I am working with JSF 2.1 and Primefaces 3.3. I am using the primefaces tree component for crating the tree from Database. I wanted to sort the tree nodes in alphabetical order at all levels. Please help me on this.
we had problems with the sorting via Comparator and found out, that there is a handy PrimeFaces TreeUtils.sortNode( TreeNode, Comparator ) class already provided which works like a charm :)
You would have to sort Primefaces DefaultTreeNode objects at the ManagedBean using Collections.sort and a Comparator class.
public TreeNodeComparator() implements Comparator<TreeNode> {
public int compare(TreeNode n1, TreeNode n2) {
// This assumes the tree node data is a string
return n1.getData().compareTo(n2.getData());
}
}
In your managed bean you will need to assemble your child lists without adding their parents yet. That can come later. For right now build your child lists out for each level and set the parent to null;
TreeNode node1 = new DefaultTreeNode("node1", null);
TreeNode node2 = new DefaultTreeNode("node2", null);
TreeNode child1node1 = new DefaultTreeNode("zgnagn", null);
TreeNode child2node1 = new DefaultTreeNode("vvnieeianag", null);
TreeNode child1node2 = new DefaultTreeNode("cajkgnagair", null);
TreeNode child2node2 = new DefaultTreeNode("ajaavnagwokd", null);
rootNodeChildren.add(node1);
rootNodeChildren.add(node2);
node1Children.add(child1node1);
node1Children.add(child2node1);
node2Children.add(child1node2);
node2Children.add(child2node2);
The reason why we are setting everything to null is because when the parent is set on the DefaultTreeNode it is added to the parents child list. The order in which you set a nodes parents determines the order they will appear in the Tree component.
Knowing that we can use our comparator to sort each list individually.
Collections.sort(rootNodeChildren, new TreeNodeComparator());
Collections.sort(node1Children, new TreeNodeComparator());
Collections.sort(node2Children, new TreeNodeComparator());
Now all of the lists are sorted so we can loop through and the appropriate parents one at a time. You can probably write an algorithm to determine this or you can keep a separate data stucture that builds the tree hierarchy without adding to the list.
Another way, and probably easier overall, is to just override the DefaultTreeNode class and give it a sort method:
public SortableDefaultTreeNode extends DefaultTreeNode {
public void sort() {
TreeNodeComparator comparator = new TreeNodeComparator();
Collections.sort(this.children, comparator);
for (TreeNode child : children) {
child.sort();
}
}
}
Now you can just build your TreeNodes out and then call root.sort() and it will recursively sort all of its children at each level alphabetically.
You could also use a generic comparable TreeNode aproach such as:
Base was taken from primefaces DefaultTreeNode, unmodified changes are left out in below code.
If child's should not be restricted on T one can use TreeNodeComparable<T extends Comparable<?>> and cast to Comparable in compareTo() method.
public class TreeNodeComparable<T extends Comparable<T>> implements TreeNode, Serializable,
Comparable<TreeNodeComparable<T>>
{
private static final long serialVersionUID = ...;
private T data;
private List<TreeNodeComparable<T>> children;
public TreeNodeComparable(final String type, final T data, final TreeNodeComparable<T> parent)
{
this.type = type;
this.data = data;
this.children = (List) new TreeNodeChildren(this);
if (parent != null)
parent.getChildren().add(this);
}
/**
* Comparison only depends on the underlying data
*
* #see ObjectUtils#compare(Comparable, Comparable)
*/
#Override
public int compareTo(final TreeNodeComparable<T> node)
{
if (node == null)
throw new NullPointerException("node");
return ObjectUtils.compare((T) this.getData(), (T) node.getData());
}
/**
* Recursively sorts the complete tree.
*/
public void sort()
{
Collections.sort(this.children);
for (final TreeNodeComparable<T> child : this.children)
{
child.sort();
// must reset parent due to PF problems
// http://forum.primefaces.org/posting.php?mode=reply&f=3&t=39752
child.setParent(this);
}
}
#SuppressWarnings("unchecked")
#Override
public boolean equals(final Object obj)
{
if (this == obj)
return true;
if (obj == null || this.getClass() != obj.getClass())
return false;
final TreeNodeComparable<T> other = (TreeNodeComparable<T>) obj;
return ObjectUtils.equals(this.data, other.data);
}
#Override
public int hashCode()
{
return new HashCodeBuilder().append(this.data).toHashCode();
}
public void setData(final Object data)
{
if (data != null && !(data instanceof Comparable))
throw new IllegalArgumentException();
this.data = (T) data;
}
#SuppressWarnings(
{
"unchecked", "rawtypes"
})
public List<TreeNode> getChildren()
{
return (List) this.children;
}
}

Resources