How does a CheckBoxTableCell propagate changes back? - java

I have a particular question about the JavaFX library that might reveal a flaw in my understanding of the JavaFX-Framework in general.
Let us assume that there is an Entity class called Entity that has a BooleanProperty called checked. Furthermore, let there be a table column as follows:
TableColumn<Entity,Boolean> checkBoxColumn;
Then the setter for the cell value factory has the following signature:
setCellValueFactory(Callback<TableColumn.CellDataFeatures<Entity,Boolean>,ObservableValue<Boolean>> value)
The following code should suffice to enable a column with checkboxes bound to the checked properties of the corresponding Entity-objects:
setCellValueFactory(new PropertyValueFactory<Entity, Boolean>("checked"));
checkBoxColumn.setCellFactory(CheckBoxTableCell.forTableColumn(checkBoxColumn));
My question in its simplest form: How does a CheckBoxTableCell set the value of the backing property considering the fact that the cell value factory returns an ObservableValue<Boolean> and not, e.g., a BooleanProperty?
The only way how I can imagine how this is done is that the CheckBoxTableCell dynamically checks whether the reference returned by the cell value factory is actually a reference to a property and then binds this property to the checked property of the checkBox.

The only way how I can imagine how this is done is that the
CheckBoxTableCell dynamically checks whether the reference returned by
the cell value factory is actually a reference to a property and then
binds this property to the checked property of the checkBox.
That's exactly what it does. Nothing sophisticated: just uses a simple instanceof check. The source code is here if you're interested enough (look at the updateItem(...) method).

Related

guice multiple bindings for a single constant

I have a java app that uses guice to do configuration.. I dont think this is what it is intended for but its what has been done and I only need to make a small change so I would prefer not to remove guice.
Basically, java properties are bound to variables, I want to bind some to an environmental variables or to a java property.
This is what I currently have
bindConstant().annotatedWith(Names.named("value")).to(properties.getProperty("java.property.value"));
this is what I would like to do
bindConstant().annotatedWith(Names.named("value")).to(System.getenv("JAVA_PROPERTY_VALUE"));
Is there a way to combine the two? I cannot do both. Or, is this just a default and I basically have what I need already? ie if I do bindConstant to System.getenv that value will be used unless its overwritten in the properties file (in my case the string constant is not the full property name so I am unsure how it works now).
I really do not know much about how guice works, I believe an injector is created where this code is and later used to do things like...
#Inject(optional = true)
#Named("value)
private String value;
I basically want that value to default to the one in the properties file, but be overridden by the env property value if its present.
I have tried simply using the env var value if it exists otherwise the property value, ie
bindConstant().annotatedWith(Names.named("value")).to(System.getenv(envVarName) != null && !System.getenv(envVarName).trim().isEmpty() ? System.getenv(envVarName) : properties.getProperty(propertyName));
Which works as expected when the environmental variable is defined and the property is not defined, but when both are defined the property is always used.
Which just leads me to the fact that I know very little about guice and how it works, I have in code a very explicit binding between the property name and this method, but, it just seems to be a default value, something after that is overwriting my value with the one from the property file.
This is super basic, but it's how we do things:
get Properties (sys.properties)
some.random.prop=localhost
iterate through System.getEnv() overriding all the Properties
// Convert SOME_RANDOM_PROP to some.random.prop
properties.put(parseKey(entry.getKey()), entry.getValue());
Now your properties should be defaulted to app.properties and overwritten with matching env.properties, then just bind all he properties.
Names.bindProperties(binder(), properties);
The caveat here is that now System.getEnv() pointless, but since you're using Guice for all your injections this shouldn't really be an issue.

What are the allowed "Default Value Literal" for an EList-typed EAttribute in an EMF Ecore model?

I want to build an .ecore model. I am using Eclipse Neon. in Design mode, I have a class and inside the class I have few attributes. when I set type of the attribute to EEList<E> [org.eclipse.emf.common.util.EList], I can't set the Default Value Literal. I don't know what is the valid value.
To answer your question, it seems you cannot set a default literal value for ELists. Or at least I could find no reference to it in any documentation, nor in the code.
For what purpose are you defining an EAttribute of type EList ? If you simply want a multi-valued feature (e.g. List) you should instead have an EAttribute of type X with multiplicity [0..*].

JPA - Using null values in #DiscriminatorValue

I was wondering if I could use the DiscriminatorValue to set apart two subtypes in the following manner:
B extends A
#DiscriminatorValue(null)
A
#DiscriminatorValue("Some-Value")
B extends A
The point is that I want to check if there is a null value in some DiscriminatorType.Char column.
I tried writing "" (empty string) as the value and also null. Niether worked.
The DiscriminatorValue is normally set by the implementation, and you should only need to set it when the implementation cannot properly tell two classes apart, like having duplicate class names or very long class names.
For example, in Hibernate/Postgres, the default discriminator is the simple class name. The only time I have ever had to set it is in deeply nested classes that run on longer than the name limit in the database.
So, long story short, don't specify a discriminator value unless you must.
Annotation do not allow a null indicator, nor does the spec directly support it.
If you are using EclipseLink, you should be able to use a DescriptorCustomizer to add a null classIndicator mapping to the A's ClassDescriptor's inhertiancePolicy.

Strategy for garbage collecting Java objects created by custom OpenOffice spreadsheet functions

I have written an OpenOffice / LibreOffice add-in that implements some custom Calc spreadsheet functions in Java. Some of these functions create Java objects that are then logically associated with the result of the function and thus also associated with the cell that the function is used in.
(Assuming for now that the function is being called from a cell formula and not from the Function Wizard or some other context).
OpenOffice does not tell custom functions which cell they are being called from, so it is not easy to figure out that association. If the parameters to the function are cell addresses then it is possible to look at those cells and find the cells that are dependent on them - this narrows down the possibilities.
It could be possible to include a unique key for the Java object in the result if it is a string, but that is ugly. I could then periodically scan all cells to make sure that the unique key is still present in one or more cells.
However, the function could also be nested within other functions in a formula, so there is no guarantee that the key will end up being visible in the resulting value of the cell.
I am looking for a clean way to detect that the logical reference to the object has gone away (because the instance of the function was called with different args, or the formula containing the function has been deleted or altered).
Edit:
Returning an XVolatileResult looked promising, however the removeResultListener() call-back is never called when a formula is deleted (except at document close).
Some more clarification:
A custom function is implemented as an instance method of an Uno component (there may be more than one custom function on a single component). Only one instance of the component is ever created.
The function method is called with string or numeric arguments, corresponding to the arguments in the spreadsheet formula. It is also possible to receive the args as cell references rather than values.
The result of the function is a string or numeric value or an XVolatileResult. It is not possible to return an arbitrary Java object.
I am creating Java objects as a side-effect of evaluating the function and I want to be able to reference those objects in other formulas in other cells.

In Hibernate, is there any difference between session.get() and session.load() besides how bad IDs are handled?

An application I'm working on does all its queries by identifier using session.load(). Given the chaos it causes when it can't find the identifier and throws an exception, I'm thinking of swapping it over to session.get(). But before I do that, it's such a fundamental part of the system that I want to make sure there's absolutely no other difference between the two methods. Is there any reason you can think of why the original developers would have chosen load() over get() aside from the handling of invalid IDs?
EDIT: As stated above, I'm fully aware that get returns false and load throws an exception. I'm asking if there's any OTHER way that they differ.
Isn't it so that Get never returns a proxy whereas Load does ?
http://ayende.com/Blog/archive/2009/04/30/nhibernate-ndash-the-difference-between-get-load-and-querying-by.aspx
I think that this is important:
Why is this useful? Well, if you know
that the value exist in the database,
and you don’t want to pay the extra
select to have that, but you want to
get that value so we can add that
reference to an object, you can use
Load to do so:
The code above will not result in a
select to the database, but when we
commit the transaction, we will set
the CustomerID column to 1. This is
how NHibernate maintain the OO facade
when giving you the same optimization
benefits of working directly with the
low level API.
From the NH 2.0 ref documentation:
Note that Load() will throw an
unrecoverable exception if there is no
matching database row. If the class is
mapped with a proxy, Load() returns an
object that is an uninitialized proxy
and does not actually hit the database
until you invoke a method of the
object. This behaviour is very useful
if you wish to create an association
to an object without actually loading
it from the database.
If you are not certain that a matching
row exists, you should use the Get()
method, which hits the database
immediately and returns null if there
is no matching row.
As usual, the best reference for this is the documentation:
Session.get():
Return the persistent instance of the given entity class with the given identifier, or null if there is no such persistent instance. (If the instance, or a proxy for the instance, is already associated with the session, return that instance or proxy.)
Session.load():
Return the persistent instance of the given entity class with the given identifier, assuming that the instance exists.
You should not use this method to determine if an instance exists (use get() instead). Use this only to retrieve an instance that you assume exists, where non-existence would be an actual error.
So, the difference is the way that non-existing instances are treated.
A good approach is shown as follows
If you need to call a getter method, then use get method. get method hits the database.
public class AccountServiceImpl implements AccountService {
private SessionFactory sessionFactory;
public BigDecimal getBalance(Integer acountId) {
// You need to know your balance
// So you need to use get method to access the database
Account account = (Account) sessionFactory.getCurrentSession().get(Account.class, accountId);
return account.getBalance();
}
}
If you need to call both getter and setter method, use get method.
In response to ChssPly's comment:
JPA with Hibernate book says about load method
The load() method always tries to return a proxy, and only returns an initialized object instance if it’s already managed by the current persistence context.
And
It hits the database as soon as you try to access the returned placeholder and force its initialization
Thus, he is right when you set up a single property.
But There is the following scenario shown in JPA with Hibernate book
It’s common to obtain a persistent instance to assign it as a reference to another instance. For example, imagine that you need the item only for a single purpose: to set an association with a Comment: aComment.setForAuction(item).
If this is all you plan to do with the item, a proxy will do fine; there is no need to
hit the database. In other words, when the Comment is saved, you need the foreign key value of an item inserted into the COMMENT table.
The proxy of an Item provides just that: an identifier value wrapped in a placeholder that looks like the real thing.
regards,

Categories