说我有以下域类。具有多对一关系的Employee
和Company
class Employee {
String id
String firstName
String lastName
String email
Company company
static mapping = {
table name: "employee"
id column: "employee_id", generator:"assigned"
version false
}
}
class Company {
String id
String name
static hasMany = [employees:Employee]
static mapping = {
table name: "company"
id column: "company_id", generator:"assigned"
autoImport false
version false
}
}
我想做的是从数据库中获取一个Company
对象,然后派生多个线程为公司创建Employees
。但是,我不确定Company
对象是否是线程安全的。
例如:
public void createEmployees(companyId, employees){
// Find the new created company - this is on the main thread
Company company = Company.findById(companyId) // Is company thread safe?
def lines = parseEmployees(employeeFile) // parses info about each employee that will later be used to create employee objects
ExecutorService executor = Executors.newFixedThreadPool(10)
List futures = new ArrayList()
lines.each { line ->
Future future = executor.submit(new Callable() {
public def call() throws Exception {
def employee = saveEmployee(line, company) // Is the company object thread safe here?
return employee
}
});
futures.add(future)
}
executor.shutdown()
for(Future future : futures){
def employee = future.get()
println employee
}
}
public Employee saveEmployee(line, company) {
Employee employee = new Employee()
employee.firstName = line.firstName
employee.lastName = line.lastName
employee.email = employee.email
employee.id = line.id
employee.company = company // thread safe?
employee.save()
}
同样,我不确定传递给Company
方法的Hibernate托管saveEmployee
对象是否是线程安全的。我的理解是Thread
中的每个Executor
都有其自己的休眠会话,该会话不是线程安全的。我以为我可能需要在merge
对象上调用attach
或Company
,但是似乎不需要。一切似乎都可以正常工作,但是很难分辨何时涉及多线程。
答案 0 :(得分:1)
在您提供的示例中,传递的Company
对象没有被修改,因此它是否是线程安全的都没有关系。 (不是这样;如果您在多个线程中对其进行更改,则会得到StaleObjectStateExceptions。)
您的Company
hasMany
名员工,并且在您当前的映射中,引用实际上存储在Employee
中(可能是company_id字段)。由于在将Company
对象与员工进行关联时并没有从技术上进行修改,因此不会造成问题。
有很多方法可以确认这一点(因为实际上很难测试所有奇怪的线程边缘情况!),但在我看来,最简单的方法可能是确认您的{{1 }}对象在添加新员工时不会增加。如果没有增加,您可以确信它没有被修改,因此线程在这里不会起作用。