I try to add compostite Index in enttiy but not work
following error got :
[error] application - message= Unexpected database state: BTree 49 is not found, cause= [ObjectDB 2.5.4] javax.persistence.PersistenceException
Unexpected database state: BTree 49 is not found (error 147
Model Classes:
#Entity
#Table(name = Customer.TABLE_NAME)
#javax.jdo.annotations.Index(members=
{"addresses.firstName,addresses.lastName,addresses.company"})
public class Customer extends ObjectDBBaseModel<Customer> {
List<Address> addresses;
}
#Entity
#Table(name = Address.TABLE_NAME)
public class Address<T extends ObjectDBBaseModel> extends ObjectDBBaseModel<T> {
public static final String TABLE_NAME = "address";
public static final Address NULL = new Address();
public static ODBFinder<Address> find = new ODBFinder<>(Address.class, NULL);
public Address() {
super((Class<T>) Address.class);
}
#Column(name = "address_type_enum")
#Enumerated(EnumType.STRING)
private AddressTypeEnum addressTypeEnum;
#Column(name = "gender_enum")
#Enumerated(EnumType.STRING)
private GenderEnum genderEnum;
private String title;
private String firstName;
private String lastName;
private String company;
private String street1;
}
The index definition is invalid, since a multi path index is limited to one entity class (and additional embeddable classes) but cannot spread over multiple entity classes.
In this case you should use two separate indexes:
Simple index on the collection of addresses.
Composite index on the three fields in Address.
ObjectDB will maintain each index separately but will join them together in relevant queries.
Related
I am trying to extract data using composite key of other table, but here problem is, I have list of composite key. Below are the table.
#Embeddable
public class IdRangePk implements Serializable {
#Column("START_RANGE")
private String startRange;
#Column("END_RANGE")
private String endRange;
// default constructor
}
#Entity
#Table(name = "ID_RANGE")
public class IdRange {
#EmbeddedId
private IdRangePk idRangePk;
#Column(name = "PARTY_ID")
private String partyId;
#Column("STATUS")
private String status; // expired or active
// constructors, other fields, getters and setters
}
Here, ID_RANGE have composite primary key (START_RANGE, END_RANGE). So same PARTY_ID can have multiple combination of start & end range.
STATUS can be either "EXPIRED" or "ACTIVE".
#Entity
#Table(name = "MESSAGE")
public class Message {
#Id
#Column("MESSAGE_Id")
private String id;
#Column(name = "PARTY_ID")
private String partyId;
#Column("START_RANGE")
private String startRange;
#Column("END_RANGE")
private String endRange;
// default constructor
// constructors, other fields, getters and setters
}
Here, I need to extract the messages having active ranges for a given PARTY_ID. Also MESSAGE_ID is the primary key.
So I divided it into two steps
Extracting active ranges for given party id
#Repository
public interface IdRangeRepo extends JpaRepository<IdRange, IdRangePk> {
List<IdRange> findByPartyIdAndStatus(String partyId, String status);
}
List<IdRange> idRanges = findByPartyIdAndStatus("123", "ACTIVE");
Extracting message from list of active IdRange
List<String> startRange = new ArrayList<>();
List<String> endRange = new ArrayList<>();
idRanges.stream().forEach(range -> {
startRange.add(range.getStartRange());
endRange.add(range.getEndRange())
});
List<Message> activeRangeMessage = findByPartyIdAndStartRangeInAndEndRangeIn("123", startRange, endRange);
#Repository
public interface MessageRepo extends JpaRepository<Message, String> {
List<IdRange> findByPartyIdAndStartRangeInAndEndRangeIn(String partyId, List<String> startRange, List<String> endRange);
}
My second step query is not right, it is extracting more rows than the expected as query is counter by individually field instead of whole (for startRange & endRange which is a composite key). Can someone please help me correct my query or provide an easiest way to extract rows. I have used derived method but #Query will also do.
I'm trying to get a single data from two tables of database. These tables doesn't have foreign keys and no jointables too. I'm using spring-data to retrieve required data for first data set.
I have two data sets that have a common String value, and want to retrieve data from both tables not using jointables or foreign keys, retrieving data from the first data set.
I'm using simple DataRepository interface
import org.springframework.data.jpa.repository.JpaRepository;
public interface DataRepository extends JpaRepository<FirstData, Long> {
DataService getById(Long id);
}
FirstData entity:
#Data
#Entity
#Table(schema = "someschema", name = "firstdata")
public class FirstData {
#Id
#Column(name = "id")
private Long uuid;
#Column(name = "name")
private String name;
#Column(name = "type")
private String type;
}
SecondData entity:
#Data
#Entity
#Table(schema = "someschema", name = "seconddata")
public class SecondData {
#Id
#Column(name = "id")
private Long uuid;
#Column(name = "type")
private String type;
#Column(name = "value")
private String value;
}
and DataService
#Service
public class DataService {
private DataRepository dataRepository;
public DataService(DataRepository dataRepository){
this.dataRepository = dataRepository;
}
public void getBothFirstAndSecondData() {
List<FirstData> firstDataSet = dataRepository.findAll();
}
}
I need to get data from both tables, but don't want to modify table structure, make jointable or add foreign keys. Also, i don't want to add another repository write code arount second data set. I need just to have a "value" from second data set at first data set result. What is the simpliest approach for solving such data retrieveing?
sql query the above problem can be:
select value from seconddata where id IN (select id from firstdata)
I want to insert doctor object to database, how should I put annotations for properties?
I tried to do it with te code shown below.
But i don't know how to do it on list properties specializations and phoneNumbers.
#Table(databaseName = WMDatabase.NAME)
public class Doctor extends BaseModel{
#Column
#PrimaryKey
#Unique(unique = true)
private String doctorId;
#Column
private FullName fullName;
#Column
private String organizationId;
#Column What shuld i put here?????
private List<Specialization> specializations;
#Column What shuld i put here?????
private Contacts contacts;
}
Below are the classes I use for doctor attributes:
public class Contacts extends BaseModel {
private List<PhoneNumber> phoneNumbers;
private String email;
private String fax;
}
public class Specialization extends BaseModel {
#Column
#PrimaryKey
#Unique(unique = true)
private String doctorId;
#Unique(unique = true)
private String specializationName;
public String getSpecializationName() {
return specializationName;
}
public void setSpecializationName(String specializationName) {
this.specializationName = specializationName;
}
DBFlow is a relational database system (not a mongo-type key/value store) and doesn't support lists as columns, according to the doc here.
List : List columns are not supported and not generally proper for a relational database. However, you can get away with a non-generic List column via a TypeConverter. But again, avoid this if you can.
The documentation on relationships may help you refine the model to suit your needs.
I want to use one class to map three tables. I know javax.persistance provides the #SecondaryTable annotation to map two tables to one class.
Below is the code, where I have used #SecondaryTable. It allows me to define only one secondary table. But I need 3 tables to be used by the same class.
#Entity
#Table(name = "table1")
#SecondaryTable(name="table2")
public class TableConfig
implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
#Id
#Column(name = "mac", table= "table1")
private String uniqueIdentifier;
I want to use one class to map three tables, From what I know is that javax.persistance provides #SecondaryTable annotation to map two tables to one class
use #SecondaryTables to map more than one table.
You can map a single entity bean to several tables using the #SecondaryTables class level annotations. To express that a column is in a particular table, use the table parameter of #Column or #JoinColumn.
for example there is 3 entity's namely: Name , Address & Student:
Name entity will look like:
#Entity
#Table(name="name")
public class Name implements Serializable {
#Id
#Column(name="id")
private int id;
#Column(name="name")
private String name;
public Name(){}
public Name(int id,String name){
this.id=id;
this.name=name;
}
//getters and setters
}
Address entity will look like:
#Entity
#Table(name="address")
public class Address implements Serializable {
#Id
#Column(name="id")
private int id;
#Column(name="address")
private String address;
public Address(){}
public Address(int id, String address) {
super();
this.id = id;
this.address = address;
}
//getters and setters
}
Student entity will look like:
#Entity
#Table(name="student")
#SecondaryTables({
#SecondaryTable(name="name", pkJoinColumns={
#PrimaryKeyJoinColumn(name="id", referencedColumnName="student_id") }),
#SecondaryTable(name="address", pkJoinColumns={
#PrimaryKeyJoinColumn(name="id", referencedColumnName="student_id") })
})
public class Student implements Serializable {
#Id
#Column(name="student_id")
private int studentId;
#Column(table="name")
private String name;
#Column(table="address")
private String address;
public Student(){}
public Student(int studentId){
this.studentId=studentId;
}
//getters and setters
}
Store like:
Student s= new Student(1);
session.save(s);
Name n=new Name(s.getStudentId(),"Bilal Hasan");
session.save(n);
Address address = new Address(s.getStudentId(), "India");
session.save(address);
Student ob = (Student)session.get(Student.class, s.getStudentId());
System.out.println(ob.getStudentId());
System.out.println(ob.getName());
System.out.println(ob.getAddress());
ouput:
1
Bilal Hasan
India
you can define one class like below :
#Entity
#Table(name="table1")
#SecondaryTables({
#SecondaryTable(name="table2", pkColumnJoins={#PrimaryKeyJoinColumn(name = "id")}),
#SecondaryTable(name="table3", pkColumnJoins={#PrimaryKeyJoinColumn(name = "id")})
})
public class TestEntity {
#Id
#GeneratedValue
private int id;
private String field1;
#Column(name="column2", table="table2")
private String field2;
#Column(name="column3", table="table3")
private String field3;
getter and setter...
}
In your DB, should has three table, and all of them should has the same primary key "id".
then, use can test like this:
TestEntity test = new TestEntity();
test.setField1("field1");
test.setField2("field2");
test.setField3("field3");
em.merge(test);
after test, in your DB, you will find one record in each table:
table1:
1, field1
table2:
1, field2
table3:
1, field3
all of them will share the primary key value. Hope this will help you.
In Hibernate mapping file you can specify the entity-name mapping with virtual name along with polymorphism="explicit" and class name would be physical class name. Like that you may do multiple mappings. While loading the object use entityname (virtual name).
The following query throws the exception:
Query query = session.createQuery("from Associate as a order by a.username asc");
associates = query.list();
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [ca.mypkg.model.Associate#0]
If I create an entry in the database with id of 0 it works just fine. I don't really get it because I'm just trying to load all the entries in the db not just a specific one.
Similar questions I've found have been concerned with trying to load an object with a given ID I'm doing no such thing.
Associate class:
#Table(name = "user")
#XmlRootElement(name = "associate")
public class Associate implements Serializable {
private String username;
private String password;
private String firstName;
private String lastName;
private String userType;
private int id;
private String email;
private String isActive;
private Department dept;
private String lastUpdated;
private String associate_type;
// ...
#Id
#GeneratedValue
public int getId() {
return id;
}
#OneToOne
#JoinColumn(name = "dept")
public Department getDept() {
return dept;
}
From my experience this type of error message usually means it does not find joined entity by mentioned id, and not the entity requested in the query (Associate, in your case).
My guess is that Associate class contains a join entity which has primitive type primary key.