Jackrabbit Oak merge not saving changes - jackrabbit

I just started to look into Jackrabbit Oak 1.7.5 and I can't get my changes saved - this test fails on the last assertion:
public class JCRTest {
#Test
public void testCommit() throws CommitFailedException {
final NodeStore ns = new MemoryNodeStore();
final String imagesFolder = "images";
NodeState rootState = ns.getRoot();
//newly created store does not have nodes
assertThat(rootState.getChildNode(imagesFolder).exists(), is(equalTo(false)));
NodeBuilder rootBuilder = rootState.builder();
//adding a node called 'images'
rootBuilder.child(imagesFolder);
//it is still not going to be shown since we are working in our own 'state'
assertThat(rootState.getChildNode(imagesFolder).exists(), is(equalTo(false)));
//merging the changes into root
ns.merge(rootBuilder, EmptyHook.INSTANCE, CommitInfo.EMPTY);
//expecting to see the 'images' folder
assertThat(rootState.getChildNode(imagesFolder).exists(), is(equalTo(true)));
}
}

A NodeState (rootState in your test) is a snapshot of the repository. After you merge your changes, you need to get head of the repository again (i.e. do rootState = ns.getRoot() again before asserting).

Related

Room Data Base Create Instance

I want to Create An Instance Of Room Data base in Composable
But
val db = Room.databaseBuilder(applicationContext, UserDatabase::class.java,"users.db").build()
is not working here not getting applicationContext
How to create an instance of context in composable
Have you tried getting the context with : val context = LocalContext.current and then adding this to get your applicationContext?
Like this: context.applicationContext or using simply val db = Room.databaseBuilder(context, UserDatabase::class.java,"users.db").build()
Room (and the underlying SQliteOpenHelper) only need the context to open the database (or more correctly to instantiate the underlying SQLiteOpenHelper).
Room/Android SQLiteOpenHelper uses the context to ascertain the Application's standard (recommended) location (data/data/<the_package_name>/databases). e.g. in the following demo (via Device Explorer):-
The database, as it is still open includes 3 files (the -wal and -shm are the Write Ahead Logging files that will at sometime be committed/written to the actual database (SQLite handles that)).
so roughly speaking Room only needs to have the context so that it can ascertain /data/data/a.a.so75008030kotlinroomgetinstancewithoutcontext/databases/testit.db (in the case of the demo).
So if you cannot use the applicationContext method then you can circumvent the need to provide the context, if using a singleton approach AND if after instantiating the singleton.
Perhaps consider this demo:-
First some pretty basic DB Stuff (table (#Entity annotated class), DAO functions and #Database annotated abstract class WITH singleton approach). BUT with some additional functions for accessing the instance without the context.
#Entity
data class TestIt(
#PrimaryKey
val testIt_id: Long?=null,
val testIt_name: String
)
#Dao
interface DAOs {
#Insert(onConflict = OnConflictStrategy.IGNORE)
fun insert(testIt: TestIt): Long
#Query("SELECT * FROM testit")
fun getAllTestItRows(): List<TestIt>
}
#Database(entities = [TestIt::class], exportSchema = false, version = 1)
abstract class TestItDatabase: RoomDatabase() {
abstract fun getDAOs(): DAOs
companion object {
private var instance: TestItDatabase?=null
/* Extra/not typical for without a context (if wanted)*/
fun isInstanceWithoutContextAvailable() : Boolean {
return instance != null
}
/******************************************************/
/* Extra/not typical for without a context */
/******************************************************/
fun getInstanceWithoutContext(): TestItDatabase? {
if (instance != null) {
return instance as TestItDatabase
}
return null
}
/* Typically the only function*/
fun getInstance(context: Context): TestItDatabase {
if (instance==null) {
instance = Room.databaseBuilder(context,TestItDatabase::class.java,"testit.db")
.allowMainThreadQueries() /* for convenience/brevity of demo */
.build()
}
return instance as TestItDatabase
}
}
}
And to demonstrate (within an activity for brevity) :-
class MainActivity : AppCompatActivity() {
lateinit var roomInstance: TestItDatabase
lateinit var dao: DAOs
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
setContentView(R.layout.activity_main)
roomInstance = TestItDatabase.getInstance(this) /* MUST be used before withoutContext functions but could be elsewhere shown here for brevity */
dao = roomInstance.getDAOs()
//dao.insert(TestIt(testIt_name = "New001")) /* Removed to test actually doing the database open with the without context */
logDataWithoutContext()
addRowWithoutContext()
addRowWithApplicationContext()
logDataWithoutContext()
}
private fun logDataWithoutContext() {
Log.d("${TAG}_LDWC","Room DB Instantiated = ${TestItDatabase.isInstanceWithoutContextAvailable()}")
for (t in TestItDatabase.getInstanceWithoutContext()!!.getDAOs().getAllTestItRows()) {
Log.d("${TAG}_LDWC_DATA","TestIt Name is ${t.testIt_name} ID is ${t.testIt_id}")
}
}
private fun addRowWithoutContext() {
Log.d("${TAG}_LDWC","Room DB Instantiated = ${TestItDatabase.isInstanceWithoutContextAvailable()}")
if (TestItDatabase.getInstanceWithoutContext()!!.getDAOs()
.insert(TestIt(System.currentTimeMillis(),"NEW AS PER ID (the time to millis) WITHOUT CONTEXT")) > 0) {
Log.d("${TAG}_ARWC_OK","Row successfully inserted.")
} else {
Log.d("${TAG}_ARWC_OUCH","Row was not successfully inserted (duplicate ID)")
}
}
private fun addRowWithApplicationContext() {
TestItDatabase.getInstance(applicationContext).getDAOs().insert(TestIt(System.currentTimeMillis() / 1000,"NEW AS PER ID (the time to seconds) WITH CONTEXT"))
}
}
The result output to the log showing that the database access, either way, worked:-
2023-01-05 12:45:39.020 D/DBINFO_LDWC: Room DB Instantiated = true
2023-01-05 12:45:39.074 D/DBINFO_LDWC: Room DB Instantiated = true
2023-01-05 12:45:39.077 D/DBINFO_ARWC_OK: Row successfully inserted.
2023-01-05 12:45:39.096 D/DBINFO_LDWC: Room DB Instantiated = true
2023-01-05 12:45:39.098 D/DBINFO_LDWC_DATA: TestIt Name is NEW AS PER ID (the time to seconds) WITH CONTEXT ID is 1672883139
2023-01-05 12:45:39.098 D/DBINFO_LDWC_DATA: TestIt Name is NEW AS PER ID (the time to millis) WITHOUT CONTEXT ID is 1672883139075
note that the shorter id was the last added but appears first due to it being selected first as it appears earlier in the index that the SQlite Query Optimiser would have used (aka the Primary Key).
basically the same date time second wise but the first insert included milliseconds whilst the insert via AddRowWithApplicationContext drops the milliseconds.

MapState does not store the previous session with EventTimeSessionWindows in Flink java

I need to compare the previous session to averages from different sessions for the same user. I'm using MapState to keep the previous session, but somehow the mapstate never contains any previous keys, so every session is new. here's my code:
SessionIdentificationProcessFunction (this is a function that gather all the events that belongs to the same session.
static SingleOutputStreamOperator<SessionEvent> sessionUser(KeyedStream<Event, String> stream) {
return stream.window(EventTimeSessionWindows.withGap(Time.minutes(PropertyFileReader.getGAP_SECTION())))
.allowedLateness(Time.minutes(PropertyFileReader.getLATENCY_ALLOWED()))
.process(new SessionIdentificationProcessFunction<Event, SessionEvent, String, TimeWindow>() {
#Override
public void open(Configuration parameters) {
/*state configured to live just one day to avoid garbage accumulation*/
StateTtlConfig ttlConfig = StateTtlConfig
.newBuilder(org.apache.flink.api.common.time.Time.days(1))
.cleanupFullSnapshot()
.build();
MapStateDescriptor<String, SessionEvent> map_descriptor = new MapStateDescriptor<>("prevMapUserSession", String.class, SessionEvent.class);
map_descriptor.enableTimeToLive(ttlConfig);
previous_user_sessions_state = getRuntimeContext().getMapState(map_descriptor);
}
#Override
public SessionEvent generateSessionRecord(String s, Context context, Iterable<Event> elements) {
Comparator<Event> sortFunc = (o1, o2) -> ((o1.timestamp.before(o2.timestamp)) ? 0 : 1);
Event start = StreamSupport.stream(elements.spliterator(), false).max(sortFunc).orElse(new Event());
Event end = StreamSupport.stream(elements.spliterator(), false).max(sortFunc).orElse(new Event());
SessionEvent session_user = (end.timestamp.equals(Timestamp.from(Instant.EPOCH))) ? new SessionEvent(start) : new SessionEvent(end);
session_user.sessionEvents = StreamSupport.stream(elements.spliterator(), false).count();
session_user.sessionDuration = sd;
try {
if (previous_user_sessions_state.contains(s)) {
SessionEvent previous = previous_user_sessions_state.get(s);
/*Update values of the session with the values of the previous which never exist and delete the previous session in the map to create a new entry with the new values updated*/
previous_user_sessions_state.remove(s);
} else {
/*always get here and create a new session*/
}
previous_user_sessions_state.put(s, session_user);
} catch (Exception e) {
e.printStackTrace();
}
return session_user;
}
})
.name("User Sessions");
}
Without seeing how SessionIdentificationProcessFunction is implemented, I'm not sure exactly what's going wrong, but Flink's session windows are rather special, so it's not terribly surprising that this isn't working. Part of the problem is that any given session window has a very short lifetime before it is merged with another session window. (As each new event arrives it is initially assigned to its own session window, after which the set of all current session windows is processed and any possible merges are performed (based on the session gap).)
What I can recommend is rather than using getRuntimeContext().getMapState(), use context.globalState().getMapState() instead (where context is the ProcessWindowFunction.Context passed to the process() method of a ProcessWindowFunction). This globalState is a KeyedStateStore meant for precisely this purpose -- keeping keyed state that is global/shared among all window instances for that key.

How to reload list resource bundle in ADF 12c

I fail to reload my resource bundle class to reflect the changed translations (made my end-user) on page. Although getContent method executes and all translations as key/value fetched from database and object[][] returned from getContent method successfully. this happens after each time I clear the cache and refresh the jsf page through actionListener.
ResourceBundle.clearCache();
Also I tried to use the below and got the same result.
ResourceBundle.clearCache(Thread.currentThread().GetContextClassLoader());
Why WLS always see the old one? Am I miss something?
versions: 12.2.1.1.0 and 12.2.1.3.0
The end user - after making the translations and contributing to the internationalization of the project, the translations are saved to the database,
The process to inforce these operations are done through the following steps:
Create a HashMap and load all the resource key/vale pairs in the map
from the database:
while (rs.next()) {
bundle.put(rs.getString(1), rs.getString(2));
}
Refresh the Bundle of your application
SoftCache cache =
(SoftCache)getFieldFromClass(ResourceBundle.class,
"cacheList");
synchronized (cache) {
ArrayList myBundles = new ArrayList();
Iterator keyIter = cache.keySet().iterator();
while (keyIter.hasNext()) {
Object key = keyIter.next();
String name =
(String)getFieldFromObject(key, "searchName");
if (name.startsWith(bundleName)) {
myBundles.add(key);
sLog.info("Resourcebundle " + name +
" will be refreshed.");
}
}
cache.keySet().removeAll(myBundles);
Getthe a String from ResourceBoundle of your application:
for (String resourcebundle : bundleNames) {
String bundleName =
resourcebundle + (bundlePostfix == null ? "" : bundlePostfix);
try {
bundle = ResourceBundle.getBundle(bundleName, locale, getCurrentLoader(bundleName));
} catch (MissingResourceException e) {
// bundle with this name not found;
}
if (bundle == null)
continue;
try {
message = bundle.getString(key);
if (message != null)
break;
} catch (Exception e) {
}
}

Find and delete inactive tfs branches

Is there any built-in way to find and delete (tf destroy) branches of TFS project that were inactive (I mean there were no check in operations) for a long time, let's say 1 month. Either tfs tools or maybe sql script that can do it would be ok.
You can do it but you need to write a small program that uses the TFS API to check each branch and delete the unused ones.
You can use a simple C# console app and I can tell you from experience that the TFS public API is quite intuitive and easy to use. You can get started with it here.
Here's how to display all the branches.
Unused branches contain element modification history, rather than deleting them writelock the branch and leave it. The space that is recovered is not significant.
Well, whole thing wasn't hard, posting code here, might help someone:
private static string _tfLocation; //location of tf.exe
private static string _tfProject; //our team project
static void Main(string[] args)
{
_tfLocation = ConfigurationManager.AppSettings.Get("tfLocation");
_tfProject = ConfigurationManager.AppSettings.Get("tfProject");
var keepAliveBranches = ConfigurationManager.AppSettings.Get("keepAliveBranches").Split(',').ToList(); //branches that we keep anyway
var latestDate = DateTime.Now.AddMonths(-3); //we delete all branches that are older than 3 months
var folders = ExecuteCommand(string.Format("dir /folders \"{0}\"", _tfProject));
var branches = folders.Split('\r', '\n').ToList();
branches = branches.Where(b => !string.IsNullOrEmpty(b) && b.StartsWith("$")).Select(b => b.Remove(0, 1)).Skip(1).ToList();
branches.ForEach(b => b = b.Remove(0, 1));
foreach (var branch in branches)
{
if (keepAliveBranches.Contains(branch))
continue;
//get latest changeset
var lastChangeset = ExecuteCommand(string.Format("history \"{0}/{1}\" /recursive /stopafter:1 /format:brief /sort:descending /noprompt", _tfProject, branch));
var changesetDate = DateTime.Parse(Regex.Match(lastChangeset, #"\d{2}\.\d{2}\.\d{4}").Value); //get it's date
if (changesetDate < latestDate)
//destroy
ExecuteCommand(string.Format("destroy \"{0}/{1}\" /recursive /stopafter:1 /startcleanup /noprompt /silent", _tfProject, branch));
}
}
//execute console command and get results
private static string ExecuteCommand(string command)
{
var process = new Process()
{
StartInfo = new ProcessStartInfo(_tfLocation)
{
UseShellExecute = false,
RedirectStandardOutput = true,
CreateNoWindow = true,
Arguments = command
},
};
process.Start();
var result = process.StandardOutput.ReadToEnd();
process.WaitForExit();
return result;
}

How to know the order of update with Domain context SubmitChanges?

Suppose I have 3 entities generated from EF, say tab1, tab2 and tab3. In SL app, I call SubmitChanges to save data to DB, all changes will be process by WCF and EF automatically.
Question is: how can I know the order of Update operation in Database?
I need to know this because I have triggers on those tables and need to know the order of the updating.
One thing you can do is to override the PeristChangeSet() in your DomainService and manually control the order of saves. Just do nothing in your regular update/insert statements. Here's some pseudocode for a saving a document exmmple to explain my answer:
[Insert]
public void InsertDocument(MyDocument objDocument) { }
[Update]
public void UpdateDocument(MyDocument objDocument) { }
protected override bool PersistChangeSet()
{
try {
// have to save document first to get its id....
MyDocument objDocumentBeingSaved = null;
foreach (ChangeSetEntry CSE in ChangeSet.ChangeSetEntries.Where(i => i.Entity is MyDocument)) {
var changedEntity = (MyDocument)CSE.Entity;
objDocumentBeingSaved = documentRepository.SaveDocument(changedEntity);
break; // only one doc
}
if (objDocumentBeingSaved == null)
throw new NullReferenceException("CreateDocumentDomainService.PersistChangeSet(): Error saving document information. Document is null in entity set.");
// save document assignments after saving document object
foreach (ChangeSetEntry CSE in ChangeSet.ChangeSetEntries.Where(i => i.Entity is DocumentAssignment)) {
var changedEntity = (DocumentAssignment)CSE.Entity;
changedEntity.DocumentId = objDocumentBeingSaved.Id;
changedEntity.Id = documentRepository.SaveDocumentAssignment(objDocumentBeingSaved, changedEntity);
}
// save line items after saving document assignments
foreach (ChangeSetEntry CSE in ChangeSet.ChangeSetEntries.Where(i => i.Entity is LineItem)) {
var changedEntity = (LineItem)CSE.Entity;
changedEntity.DocumentId = objDocumentBeingSaved.Id;
changedEntity.Id = documentRepository.SaveLineItem(objDocumentBeingSaved, changedEntity);
}
documentRepository.GenerateDocumentNumber(objDocumentBeingSaved.Id);
}
catch {
// ....
throw;
}
return false;
}

Resources